changeset 3469:50fe4b116ef4

Merge
author lana
date Thu, 10 Jul 2014 12:39:26 -0700
parents 14cf3ffab2b7 1ea840327bf6
children 31b95f27e9ea
files test/tools/javac/enum/T5081785a.java test/tools/javac/enum/T5081785b.java test/tools/javac/enum/T5081785c.java
diffstat 142 files changed, 3892 insertions(+), 2829 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/api/JavacScope.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/api/JavacScope.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -46,18 +46,33 @@
  * @author Jonathan Gibbons;
  */
 public class JavacScope implements com.sun.source.tree.Scope {
+
+    static JavacScope create(Env<AttrContext> env) {
+        if (env.outer == null || env.outer == env) {
+            //the "top-level" scope needs to return both imported and defined elements
+            //see test CheckLocalElements
+            return new JavacScope(env) {
+                @Override
+                public Iterable<? extends Element> getLocalElements() {
+                    return env.toplevel.namedImportScope.getSymbols();
+                }
+            };
+        } else {
+            return new JavacScope(env);
+        }
+    }
+
     protected final Env<AttrContext> env;
 
-    /** Creates a new instance of JavacScope */
-    JavacScope(Env<AttrContext> env) {
+    private JavacScope(Env<AttrContext> env) {
         env.getClass(); // null-check
         this.env = env;
     }
 
     public JavacScope getEnclosingScope() {
-        if (env.outer != null && env.outer != env)
-            return  new JavacScope(env.outer);
-        else {
+        if (env.outer != null && env.outer != env) {
+            return create(env.outer);
+        } else {
             // synthesize an outermost "star-import" scope
             return new JavacScope(env) {
                 public boolean isStarImportScope() {
@@ -67,7 +82,7 @@
                     return null;
                 }
                 public Iterable<? extends Element> getLocalElements() {
-                    return env.toplevel.starImportScope.getElements();
+                    return env.toplevel.starImportScope.getSymbols();
                 }
             };
         }
--- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Thu Jul 10 12:39:26 2014 -0700
@@ -456,10 +456,9 @@
         }
         searched.add(tsym);
 
-        for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(fieldName);
-                e.scope != null; e = e.next()) {
-            if (e.sym.kind == Kinds.VAR) {
-                return (VarSymbol)e.sym;
+        for (Symbol sym : tsym.members().getSymbolsByName(fieldName)) {
+            if (sym.kind == Kinds.VAR) {
+                return (VarSymbol)sym;
             }
         }
 
@@ -499,11 +498,10 @@
 
     /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */
     MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
-        for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(names.init);
-                e.scope != null; e = e.next()) {
-            if (e.sym.kind == Kinds.MTH) {
-                if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
-                    return (MethodSymbol) e.sym;
+        for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
+            if (sym.kind == Kinds.MTH) {
+                if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
+                    return (MethodSymbol) sym;
                 }
             }
         }
@@ -529,7 +527,6 @@
         searched.add(tsym);
 
         // search current class
-        com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(methodName);
 
         //### Using modifier filter here isn't really correct,
         //### but emulates the old behavior.  Instead, we should
@@ -542,10 +539,10 @@
             // In order to provide textually identical results, we
             // attempt to emulate the old behavior.
             MethodSymbol lastFound = null;
-            for (; e.scope != null; e = e.next()) {
-                if (e.sym.kind == Kinds.MTH) {
-                    if (e.sym.name == methodName) {
-                        lastFound = (MethodSymbol)e.sym;
+            for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
+                if (sym.kind == Kinds.MTH) {
+                    if (sym.name == methodName) {
+                        lastFound = (MethodSymbol)sym;
                     }
                 }
             }
@@ -553,11 +550,11 @@
                 return lastFound;
             }
         } else {
-            for (; e.scope != null; e = e.next()) {
-                if (e.sym != null &&
-                    e.sym.kind == Kinds.MTH) {
-                    if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
-                        return (MethodSymbol) e.sym;
+            for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
+                if (sym != null &&
+                    sym.kind == Kinds.MTH) {
+                    if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
+                        return (MethodSymbol) sym;
                     }
                 }
             }
@@ -684,7 +681,7 @@
     }
 
     public JavacScope getScope(TreePath path) {
-        return new JavacScope(getAttrContext(path));
+        return JavacScope.create(getAttrContext(path));
     }
 
     public String getDocComment(TreePath path) {
--- a/src/share/classes/com/sun/tools/javac/code/ClassFinder.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/ClassFinder.java	Thu Jul 10 12:39:26 2014 -0700
@@ -37,6 +37,7 @@
 import static javax.tools.StandardLocation.*;
 
 import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.util.*;
@@ -218,7 +219,7 @@
         if (c.owner.kind == PCK) {
             Symbol owner = c.owner;
             for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
-                Symbol encl = owner.members().lookup(name).sym;
+                Symbol encl = owner.members().findFirst(name);
                 if (encl == null)
                     encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
                 if (encl != null)
@@ -335,7 +336,7 @@
         boolean isPkgInfo = classname == names.package_info;
         ClassSymbol c = isPkgInfo
             ? p.package_info
-            : (ClassSymbol) p.members_field.lookup(classname).sym;
+            : (ClassSymbol) p.members_field.findFirst(classname);
         if (c == null) {
             c = syms.enterClass(classname, p);
             if (c.classfile == null) // only update the file if's it's newly created
@@ -399,7 +400,7 @@
      */
     private void fillIn(PackageSymbol p) throws IOException {
         if (p.members_field == null)
-            p.members_field = new Scope(p);
+            p.members_field = WriteableScope.create(p);
 
         preferCurrent = false;
         if (userPathsFirst) {
--- a/src/share/classes/com/sun/tools/javac/code/Scope.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Scope.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -25,440 +25,588 @@
 
 package com.sun.tools.javac.code;
 
-import java.util.Iterator;
+import java.util.*;
 
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.List;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static com.sun.tools.javac.code.Scope.LookupKind.RECURSIVE;
 
 /** A scope represents an area of visibility in a Java program. The
  *  Scope class is a container for symbols which provides
  *  efficient access to symbols given their names. Scopes are implemented
  *  as hash tables with "open addressing" and "double hashing".
- *  Scopes can be nested; the next field of a scope points
- *  to its next outer scope. Nested scopes can share their hash tables.
+ *  Scopes can be nested. Nested scopes can share their hash tables.
  *
  *  <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>
  */
-public class Scope {
-
-    /** The number of scopes that share this scope's hash table.
-     */
-    private int shared;
-
-    /** Next enclosing scope (with whom this scope may share a hashtable)
-     */
-    public Scope next;
+public abstract class Scope {
 
     /** The scope's owner.
      */
-    public Symbol owner;
+    public final Symbol owner;
 
-    /** A hash table for the scope's entries.
+    protected Scope(Symbol owner) {
+        this.owner = owner;
+    }
+
+    /**Returns all Symbols in this Scope. Symbols from outward Scopes are included.
      */
-    Entry[] table;
+    public final Iterable<Symbol> getSymbols() {
+        return getSymbols(noFilter);
+    }
 
-    /** Mask for hash codes, always equal to (table.length - 1).
+    /**Returns Symbols that match the given filter. Symbols from outward Scopes are included.
      */
-    int hashMask;
+    public final Iterable<Symbol> getSymbols(Filter<Symbol> sf) {
+        return getSymbols(sf, RECURSIVE);
+    }
 
-    /** A linear list that also contains all entries in
-     *  reverse order of appearance (i.e later entries are pushed on top).
+    /**Returns all Symbols in this Scope. Symbols from outward Scopes are included
+     * iff lookupKind == RECURSIVE.
      */
-    public Entry elems;
+    public final Iterable<Symbol> getSymbols(LookupKind lookupKind) {
+        return getSymbols(noFilter, lookupKind);
+    }
 
-    /** The number of elements in this scope.
-     * This includes deleted elements, whose value is the sentinel.
+    /**Returns Symbols that match the given filter. Symbols from outward Scopes are included
+     * iff lookupKind == RECURSIVE.
      */
-    int nelems = 0;
+    public abstract Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind);
+
+    /**Returns Symbols with the given name. Symbols from outward Scopes are included.
+     */
+    public final Iterable<Symbol> getSymbolsByName(Name name) {
+        return getSymbolsByName(name, RECURSIVE);
+    }
+
+    /**Returns Symbols with the given name that match the given filter.
+     * Symbols from outward Scopes are included.
+     */
+    public final Iterable<Symbol> getSymbolsByName(final Name name, final Filter<Symbol> sf) {
+        return getSymbolsByName(name, sf, RECURSIVE);
+    }
+
+    /**Returns Symbols with the given name. Symbols from outward Scopes are included
+     * iff lookupKind == RECURSIVE.
+     */
+    public final Iterable<Symbol> getSymbolsByName(Name name, LookupKind lookupKind) {
+        return getSymbolsByName(name, noFilter, lookupKind);
+    }
+
+    /**Returns Symbols with the given name that match the given filter.
+     * Symbols from outward Scopes are included iff lookupKind == RECURSIVE.
+     */
+    public abstract Iterable<Symbol> getSymbolsByName(final Name name, final Filter<Symbol> sf,
+            final LookupKind lookupKind);
+
+    /** Return the first Symbol from this or outward scopes with the given name.
+     * Returns null if none.
+     */
+    public final Symbol findFirst(Name name) {
+        return findFirst(name, noFilter);
+    }
+
+    /** Return the first Symbol from this or outward scopes with the given name that matches the
+     *  given filter. Returns null if none.
+     */
+    public Symbol findFirst(Name name, Filter<Symbol> sf) {
+        Iterator<Symbol> it = getSymbolsByName(name, sf).iterator();
+        return it.hasNext() ? it.next() : null;
+    }
+
+    /** Returns true iff there are is at least one Symbol in this scope matching the given filter.
+     *  Does not inspect outward scopes.
+     */
+    public boolean anyMatch(Filter<Symbol> filter) {
+        return getSymbols(filter, NON_RECURSIVE).iterator().hasNext();
+    }
+
+    /** Returns true iff the given Symbol is in this scope or any outward scope.
+     */
+    public boolean includes(final Symbol sym) {
+        return getSymbolsByName(sym.name, new Filter<Symbol>() {
+            @Override
+            public boolean accepts(Symbol t) {
+                return t == sym;
+            }
+        }).iterator().hasNext();
+    }
+
+    /** Returns true iff this scope does not contain any Symbol. Does not inspect outward scopes.
+     */
+    public boolean isEmpty() {
+        return !getSymbols(NON_RECURSIVE).iterator().hasNext();
+    }
+
+    /** Returns the Scope from which the givins Symbol originates in this scope.
+     */
+    public abstract Scope getOrigin(Symbol byName);
+
+    /** Returns true iff the given Symbol is part of this scope due to a static import.
+     */
+    public abstract boolean isStaticallyImported(Symbol byName);
+
+    private static final Filter<Symbol> noFilter = null;
 
     /** A list of scopes to be notified if items are to be removed from this scope.
      */
     List<ScopeListener> listeners = List.nil();
 
-    /** Use as a "not-found" result for lookup.
-     * Also used to mark deleted entries in the table.
-     */
-    private static final Entry sentinel = new Entry(null, null, null, null);
-
-    /** The hash table's initial size.
-     */
-    private static final int INITIAL_SIZE = 0x10;
-
-    /** A value for the empty scope.
-     */
-    public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
-
-    /** Construct a new scope, within scope next, with given owner, using
-     *  given table. The table's length must be an exponent of 2.
-     */
-    private Scope(Scope next, Symbol owner, Entry[] table) {
-        this.next = next;
-        Assert.check(emptyScope == null || owner != null);
-        this.owner = owner;
-        this.table = table;
-        this.hashMask = table.length - 1;
+    public void addScopeListener(ScopeListener sl) {
+        listeners = listeners.prepend(sl);
     }
 
-    /** Convenience constructor used for dup and dupUnshared. */
-    private Scope(Scope next, Symbol owner, Entry[] table, int nelems) {
-        this(next, owner, table);
-        this.nelems = nelems;
-    }
-
-    /** Construct a new scope, within scope next, with given owner,
-     *  using a fresh table of length INITIAL_SIZE.
-     */
-    public Scope(Symbol owner) {
-        this(null, owner, new Entry[INITIAL_SIZE]);
-    }
-
-    /** Construct a fresh scope within this scope, with same owner,
-     *  which shares its table with the outer scope. Used in connection with
-     *  method leave if scope access is stack-like in order to avoid allocation
-     *  of fresh tables.
-     */
-    public Scope dup() {
-        return dup(this.owner);
-    }
-
-    /** Construct a fresh scope within this scope, with new owner,
-     *  which shares its table with the outer scope. Used in connection with
-     *  method leave if scope access is stack-like in order to avoid allocation
-     *  of fresh tables.
-     */
-    public Scope dup(Symbol newOwner) {
-        Scope result = new Scope(this, newOwner, this.table, this.nelems);
-        shared++;
-        // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
-        // new Error().printStackTrace(System.out);
-        return result;
-    }
-
-    /** Construct a fresh scope within this scope, with same owner,
-     *  with a new hash table, whose contents initially are those of
-     *  the table of its outer scope.
-     */
-    public Scope dupUnshared() {
-        return new Scope(this, this.owner, this.table.clone(), this.nelems);
-    }
-
-    /** Remove all entries of this scope from its table, if shared
-     *  with next.
-     */
-    public Scope leave() {
-        Assert.check(shared == 0);
-        if (table != next.table) return next;
-        while (elems != null) {
-            int hash = getIndex(elems.sym.name);
-            Entry e = table[hash];
-            Assert.check(e == elems, elems.sym);
-            table[hash] = elems.shadowed;
-            elems = elems.sibling;
-        }
-        Assert.check(next.shared > 0);
-        next.shared--;
-        next.nelems = nelems;
-        // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
-        // new Error().printStackTrace(System.out);
-        return next;
-    }
-
-    /** Double size of hash table.
-     */
-    private void dble() {
-        Assert.check(shared == 0);
-        Entry[] oldtable = table;
-        Entry[] newtable = new Entry[oldtable.length * 2];
-        for (Scope s = this; s != null; s = s.next) {
-            if (s.table == oldtable) {
-                Assert.check(s == this || s.shared != 0);
-                s.table = newtable;
-                s.hashMask = newtable.length - 1;
-            }
-        }
-        int n = 0;
-        for (int i = oldtable.length; --i >= 0; ) {
-            Entry e = oldtable[i];
-            if (e != null && e != sentinel) {
-                table[getIndex(e.sym.name)] = e;
-                n++;
-            }
-        }
-        // We don't need to update nelems for shared inherited scopes,
-        // since that gets handled by leave().
-        nelems = n;
-    }
-
-    /** Enter symbol sym in this scope.
-     */
-    public void enter(Symbol sym) {
-        Assert.check(shared == 0);
-        enter(sym, this);
-    }
-
-    public void enter(Symbol sym, Scope s) {
-        enter(sym, s, s, false);
-    }
-
-    /**
-     * Enter symbol sym in this scope, but mark that it comes from
-     * given scope `s' accessed through `origin'.  The last two
-     * arguments are only used in import scopes.
-     */
-    public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
-        Assert.check(shared == 0);
-        if (nelems * 3 >= hashMask * 2)
-            dble();
-        int hash = getIndex(sym.name);
-        Entry old = table[hash];
-        if (old == null) {
-            old = sentinel;
-            nelems++;
-        }
-        Entry e = makeEntry(sym, old, elems, s, origin, staticallyImported);
-        table[hash] = e;
-        elems = e;
-
-        //notify listeners
-        for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
-            l.head.symbolAdded(sym, this);
-        }
-    }
-
-    Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin, boolean staticallyImported) {
-        return new Entry(sym, shadowed, sibling, scope);
-    }
-
-
     public interface ScopeListener {
         public void symbolAdded(Symbol sym, Scope s);
         public void symbolRemoved(Symbol sym, Scope s);
     }
 
-    public void addScopeListener(ScopeListener sl) {
-        listeners = listeners.prepend(sl);
+    public enum LookupKind {
+        RECURSIVE,
+        NON_RECURSIVE;
     }
 
-    /** Remove symbol from this scope.  Used when an inner class
-     *  attribute tells us that the class isn't a package member.
-     */
-    public void remove(Symbol sym) {
-        Assert.check(shared == 0);
-        Entry e = lookup(sym.name);
-        if (e.scope == null) return;
+    /**A scope into which Symbols can be added.*/
+    public abstract static class WriteableScope extends Scope {
 
-        // remove e from table and shadowed list;
-        int i = getIndex(sym.name);
-        Entry te = table[i];
-        if (te == e)
-            table[i] = e.shadowed;
-        else while (true) {
-            if (te.shadowed == e) {
-                te.shadowed = e.shadowed;
-                break;
-            }
-            te = te.shadowed;
+        public WriteableScope(Symbol owner) {
+            super(owner);
         }
 
-        // remove e from elems and sibling list
-        te = elems;
-        if (te == e)
-            elems = e.sibling;
-        else while (true) {
-            if (te.sibling == e) {
-                te.sibling = e.sibling;
-                break;
-            }
-            te = te.sibling;
+        /** Enter the given Symbol into this scope.
+         */
+        public abstract void enter(Symbol c);
+        /** Enter symbol sym in this scope if not already there.
+         */
+        public abstract void enterIfAbsent(Symbol c);
+
+        public abstract void remove(Symbol c);
+
+        /** Construct a fresh scope within this scope, with same owner. The new scope may
+         *  shares internal structures with the this scope. Used in connection with
+         *  method leave if scope access is stack-like in order to avoid allocation
+         *  of fresh tables.
+         */
+        public final WriteableScope dup() {
+            return dup(this.owner);
         }
 
-        //notify listeners
-        for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
-            l.head.symbolRemoved(sym, this);
+        /** Construct a fresh scope within this scope, with new owner. The new scope may
+         *  shares internal structures with the this scope. Used in connection with
+         *  method leave if scope access is stack-like in order to avoid allocation
+         *  of fresh tables.
+         */
+        public abstract WriteableScope dup(Symbol newOwner);
+
+        /** Must be called on dup-ed scopes to be able to work with the outward scope again.
+         */
+        public abstract WriteableScope leave();
+
+        /** Construct a fresh scope within this scope, with same owner. The new scope
+         *  will not share internal structures with this scope.
+         */
+        public final WriteableScope dupUnshared() {
+            return dupUnshared(owner);
         }
+
+        /** Construct a fresh scope within this scope, with new owner. The new scope
+         *  will not share internal structures with this scope.
+         */
+        public abstract WriteableScope dupUnshared(Symbol newOwner);
+
+        /** Create a new WriteableScope.
+         */
+        public static WriteableScope create(Symbol owner) {
+            return new ScopeImpl(owner);
+        }
+
     }
 
-    /** Enter symbol sym in this scope if not already there.
-     */
-    public void enterIfAbsent(Symbol sym) {
-        Assert.check(shared == 0);
-        Entry e = lookup(sym.name);
-        while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
-        if (e.scope != this) enter(sym);
-    }
+    private static class ScopeImpl extends WriteableScope {
+        /** The number of scopes that share this scope's hash table.
+         */
+        private int shared;
 
-    /** Given a class, is there already a class with same fully
-     *  qualified name in this (import) scope?
-     */
-    public boolean includes(Symbol c) {
-        for (Scope.Entry e = lookup(c.name);
-             e.scope == this;
-             e = e.next()) {
-            if (e.sym == c) return true;
+        /** Next enclosing scope (with whom this scope may share a hashtable)
+         */
+        public ScopeImpl next;
+
+        /** A hash table for the scope's entries.
+         */
+        Entry[] table;
+
+        /** Mask for hash codes, always equal to (table.length - 1).
+         */
+        int hashMask;
+
+        /** A linear list that also contains all entries in
+         *  reverse order of appearance (i.e later entries are pushed on top).
+         */
+        public Entry elems;
+
+        /** The number of elements in this scope.
+         * This includes deleted elements, whose value is the sentinel.
+         */
+        int nelems = 0;
+
+        /** Use as a "not-found" result for lookup.
+         * Also used to mark deleted entries in the table.
+         */
+        private static final Entry sentinel = new Entry(null, null, null, null);
+
+        /** The hash table's initial size.
+         */
+        private static final int INITIAL_SIZE = 0x10;
+
+        /** Construct a new scope, within scope next, with given owner, using
+         *  given table. The table's length must be an exponent of 2.
+         */
+        private ScopeImpl(ScopeImpl next, Symbol owner, Entry[] table) {
+            super(owner);
+            this.next = next;
+            Assert.check(owner != null);
+            this.table = table;
+            this.hashMask = table.length - 1;
         }
-        return false;
-    }
 
-    static final Filter<Symbol> noFilter = new Filter<Symbol>() {
-        public boolean accepts(Symbol s) {
-            return true;
+        /** Convenience constructor used for dup and dupUnshared. */
+        private ScopeImpl(ScopeImpl next, Symbol owner, Entry[] table, int nelems) {
+            this(next, owner, table);
+            this.nelems = nelems;
         }
-    };
 
-    /** Return the entry associated with given name, starting in
-     *  this scope and proceeding outwards. If no entry was found,
-     *  return the sentinel, which is characterized by having a null in
-     *  both its scope and sym fields, whereas both fields are non-null
-     *  for regular entries.
-     */
-    public Entry lookup(Name name) {
-        return lookup(name, noFilter);
-    }
+        /** Construct a new scope, within scope next, with given owner,
+         *  using a fresh table of length INITIAL_SIZE.
+         */
+        public ScopeImpl(Symbol owner) {
+            this(null, owner, new Entry[INITIAL_SIZE]);
+        }
 
-    public Entry lookup(Name name, Filter<Symbol> sf) {
-        Entry e = table[getIndex(name)];
-        if (e == null || e == sentinel)
-            return sentinel;
-        while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
-            e = e.shadowed;
-        return e;
-    }
+        /** Construct a fresh scope within this scope, with new owner,
+         *  which shares its table with the outer scope. Used in connection with
+         *  method leave if scope access is stack-like in order to avoid allocation
+         *  of fresh tables.
+         */
+        public WriteableScope dup(Symbol newOwner) {
+            ScopeImpl result = new ScopeImpl(this, newOwner, this.table, this.nelems);
+            shared++;
+            // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
+            // new Error().printStackTrace(System.out);
+            return result;
+        }
 
-    /*void dump (java.io.PrintStream out) {
-        out.println(this);
-        for (int l=0; l < table.length; l++) {
-            Entry le = table[l];
-            out.print("#"+l+": ");
-            if (le==sentinel) out.println("sentinel");
-            else if(le == null) out.println("null");
-            else out.println(""+le+" s:"+le.sym);
+        /** Construct a fresh scope within this scope, with new owner,
+         *  with a new hash table, whose contents initially are those of
+         *  the table of its outer scope.
+         */
+        public WriteableScope dupUnshared(Symbol newOwner) {
+            return new ScopeImpl(this, newOwner, this.table.clone(), this.nelems);
         }
-    }*/
 
-    /** Look for slot in the table.
-     *  We use open addressing with double hashing.
-     */
-    int getIndex (Name name) {
-        int h = name.hashCode();
-        int i = h & hashMask;
-        // The expression below is always odd, so it is guaranteed
-        // to be mutually prime with table.length, a power of 2.
-        int x = hashMask - ((h + (h >> 16)) << 1);
-        int d = -1; // Index of a deleted item.
-        for (;;) {
-            Entry e = table[i];
-            if (e == null)
-                return d >= 0 ? d : i;
-            if (e == sentinel) {
-                // We have to keep searching even if we see a deleted item.
-                // However, remember the index in case we fail to find the name.
-                if (d < 0)
-                    d = i;
-            } else if (e.sym.name == name)
-                return i;
-            i = (i + x) & hashMask;
+        /** Remove all entries of this scope from its table, if shared
+         *  with next.
+         */
+        public WriteableScope leave() {
+            Assert.check(shared == 0);
+            if (table != next.table) return next;
+            while (elems != null) {
+                int hash = getIndex(elems.sym.name);
+                Entry e = table[hash];
+                Assert.check(e == elems, elems.sym);
+                table[hash] = elems.shadowed;
+                elems = elems.sibling;
+            }
+            Assert.check(next.shared > 0);
+            next.shared--;
+            next.nelems = nelems;
+            // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
+            // new Error().printStackTrace(System.out);
+            return next;
         }
-    }
 
-    public boolean anyMatch(Filter<Symbol> sf) {
-        return getElements(sf).iterator().hasNext();
-    }
+        /** Double size of hash table.
+         */
+        private void dble() {
+            Assert.check(shared == 0);
+            Entry[] oldtable = table;
+            Entry[] newtable = new Entry[oldtable.length * 2];
+            for (ScopeImpl s = this; s != null; s = s.next) {
+                if (s.table == oldtable) {
+                    Assert.check(s == this || s.shared != 0);
+                    s.table = newtable;
+                    s.hashMask = newtable.length - 1;
+                }
+            }
+            int n = 0;
+            for (int i = oldtable.length; --i >= 0; ) {
+                Entry e = oldtable[i];
+                if (e != null && e != sentinel) {
+                    table[getIndex(e.sym.name)] = e;
+                    n++;
+                }
+            }
+            // We don't need to update nelems for shared inherited scopes,
+            // since that gets handled by leave().
+            nelems = n;
+        }
 
-    public Iterable<Symbol> getElements() {
-        return getElements(noFilter);
-    }
+        /** Enter symbol sym in this scope.
+         */
+        public void enter(Symbol sym) {
+            Assert.check(shared == 0);
+            if (nelems * 3 >= hashMask * 2)
+                dble();
+            int hash = getIndex(sym.name);
+            Entry old = table[hash];
+            if (old == null) {
+                old = sentinel;
+                nelems++;
+            }
+            Entry e = new Entry(sym, old, elems, this);
+            table[hash] = e;
+            elems = e;
 
-    public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
-        return new Iterable<Symbol>() {
-            public Iterator<Symbol> iterator() {
-                return new Iterator<Symbol>() {
-                    private Scope currScope = Scope.this;
-                    private Scope.Entry currEntry = elems;
-                    {
-                        update();
-                    }
-
-                    public boolean hasNext() {
-                        return currEntry != null;
-                    }
-
-                    public Symbol next() {
-                        Symbol sym = (currEntry == null ? null : currEntry.sym);
-                        if (currEntry != null) {
-                            currEntry = currEntry.sibling;
-                        }
-                        update();
-                        return sym;
-                    }
-
-                    public void remove() {
-                        throw new UnsupportedOperationException();
-                    }
-
-                    private void update() {
-                        skipToNextMatchingEntry();
-                        while (currEntry == null && currScope.next != null) {
-                            currScope = currScope.next;
-                            currEntry = currScope.elems;
-                            skipToNextMatchingEntry();
-                        }
-                    }
-
-                    void skipToNextMatchingEntry() {
-                        while (currEntry != null && !sf.accepts(currEntry.sym)) {
-                            currEntry = currEntry.sibling;
-                        }
-                    }
-                };
-            }
-        };
-    }
-
-    public Iterable<Symbol> getElementsByName(Name name) {
-        return getElementsByName(name, noFilter);
-    }
-
-    public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
-        return new Iterable<Symbol>() {
-            public Iterator<Symbol> iterator() {
-                 return new Iterator<Symbol>() {
-                    Scope.Entry currentEntry = lookup(name, sf);
-
-                    public boolean hasNext() {
-                        return currentEntry.scope != null;
-                    }
-                    public Symbol next() {
-                        Scope.Entry prevEntry = currentEntry;
-                        currentEntry = currentEntry.next(sf);
-                        return prevEntry.sym;
-                    }
-                    public void remove() {
-                        throw new UnsupportedOperationException();
-                    }
-                };
-            }
-        };
-    }
-
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("Scope[");
-        for (Scope s = this; s != null ; s = s.next) {
-            if (s != this) result.append(" | ");
-            for (Entry e = s.elems; e != null; e = e.sibling) {
-                if (e != s.elems) result.append(", ");
-                result.append(e.sym);
+            //notify listeners
+            for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
+                l.head.symbolAdded(sym, this);
             }
         }
-        result.append("]");
-        return result.toString();
+
+        /** Remove symbol from this scope.  Used when an inner class
+         *  attribute tells us that the class isn't a package member.
+         */
+        public void remove(Symbol sym) {
+            Assert.check(shared == 0);
+            Entry e = lookup(sym.name);
+            if (e.scope == null) return;
+
+            // remove e from table and shadowed list;
+            int i = getIndex(sym.name);
+            Entry te = table[i];
+            if (te == e)
+                table[i] = e.shadowed;
+            else while (true) {
+                if (te.shadowed == e) {
+                    te.shadowed = e.shadowed;
+                    break;
+                }
+                te = te.shadowed;
+            }
+
+            // remove e from elems and sibling list
+            te = elems;
+            if (te == e)
+                elems = e.sibling;
+            else while (true) {
+                if (te.sibling == e) {
+                    te.sibling = e.sibling;
+                    break;
+                }
+                te = te.sibling;
+            }
+
+            //notify listeners
+            for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
+                l.head.symbolRemoved(sym, this);
+            }
+        }
+
+        /** Enter symbol sym in this scope if not already there.
+         */
+        public void enterIfAbsent(Symbol sym) {
+            Assert.check(shared == 0);
+            Entry e = lookup(sym.name);
+            while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
+            if (e.scope != this) enter(sym);
+        }
+
+        /** Given a class, is there already a class with same fully
+         *  qualified name in this (import) scope?
+         */
+        public boolean includes(Symbol c) {
+            for (Scope.Entry e = lookup(c.name);
+                 e.scope == this;
+                 e = e.next()) {
+                if (e.sym == c) return true;
+            }
+            return false;
+        }
+
+        /** Return the entry associated with given name, starting in
+         *  this scope and proceeding outwards. If no entry was found,
+         *  return the sentinel, which is characterized by having a null in
+         *  both its scope and sym fields, whereas both fields are non-null
+         *  for regular entries.
+         */
+        protected Entry lookup(Name name) {
+            return lookup(name, noFilter);
+        }
+
+        protected Entry lookup(Name name, Filter<Symbol> sf) {
+            Entry e = table[getIndex(name)];
+            if (e == null || e == sentinel)
+                return sentinel;
+            while (e.scope != null && (e.sym.name != name || (sf != null && !sf.accepts(e.sym))))
+                e = e.shadowed;
+            return e;
+        }
+
+        public Symbol findFirst(Name name, Filter<Symbol> sf) {
+            return lookup(name, sf).sym;
+        }
+
+        /*void dump (java.io.PrintStream out) {
+            out.println(this);
+            for (int l=0; l < table.length; l++) {
+                Entry le = table[l];
+                out.print("#"+l+": ");
+                if (le==sentinel) out.println("sentinel");
+                else if(le == null) out.println("null");
+                else out.println(""+le+" s:"+le.sym);
+            }
+        }*/
+
+        /** Look for slot in the table.
+         *  We use open addressing with double hashing.
+         */
+        int getIndex (Name name) {
+            int h = name.hashCode();
+            int i = h & hashMask;
+            // The expression below is always odd, so it is guaranteed
+            // to be mutually prime with table.length, a power of 2.
+            int x = hashMask - ((h + (h >> 16)) << 1);
+            int d = -1; // Index of a deleted item.
+            for (;;) {
+                Entry e = table[i];
+                if (e == null)
+                    return d >= 0 ? d : i;
+                if (e == sentinel) {
+                    // We have to keep searching even if we see a deleted item.
+                    // However, remember the index in case we fail to find the name.
+                    if (d < 0)
+                        d = i;
+                } else if (e.sym.name == name)
+                    return i;
+                i = (i + x) & hashMask;
+            }
+        }
+
+        public boolean anyMatch(Filter<Symbol> sf) {
+            return getSymbols(sf, NON_RECURSIVE).iterator().hasNext();
+        }
+
+        public Iterable<Symbol> getSymbols(final Filter<Symbol> sf,
+                                           final LookupKind lookupKind) {
+            return new Iterable<Symbol>() {
+                public Iterator<Symbol> iterator() {
+                    return new Iterator<Symbol>() {
+                        private ScopeImpl currScope = ScopeImpl.this;
+                        private Scope.Entry currEntry = elems;
+                        {
+                            update();
+                        }
+
+                        public boolean hasNext() {
+                            return currEntry != null;
+                        }
+
+                        public Symbol next() {
+                            Symbol sym = (currEntry == null ? null : currEntry.sym);
+                            if (currEntry != null) {
+                                currEntry = currEntry.sibling;
+                            }
+                            update();
+                            return sym;
+                        }
+
+                        public void remove() {
+                            throw new UnsupportedOperationException();
+                        }
+
+                        private void update() {
+                            skipToNextMatchingEntry();
+                            if (lookupKind == RECURSIVE) {
+                                while (currEntry == null && currScope.next != null) {
+                                    currScope = currScope.next;
+                                    currEntry = currScope.elems;
+                                    skipToNextMatchingEntry();
+                                }
+                            }
+                        }
+
+                        void skipToNextMatchingEntry() {
+                            while (currEntry != null && sf != null && !sf.accepts(currEntry.sym)) {
+                                currEntry = currEntry.sibling;
+                            }
+                        }
+                    };
+                }
+            };
+        }
+
+        public Iterable<Symbol> getSymbolsByName(final Name name,
+                                                 final Filter<Symbol> sf,
+                                                 final LookupKind lookupKind) {
+            return new Iterable<Symbol>() {
+                public Iterator<Symbol> iterator() {
+                     return new Iterator<Symbol>() {
+                        Scope.Entry currentEntry = lookup(name, sf);
+
+                        public boolean hasNext() {
+                            return currentEntry.scope != null &&
+                                    (lookupKind == RECURSIVE ||
+                                     currentEntry.scope == ScopeImpl.this);
+                        }
+                        public Symbol next() {
+                            Scope.Entry prevEntry = currentEntry;
+                            currentEntry = currentEntry.next(sf);
+                            return prevEntry.sym;
+                        }
+                        public void remove() {
+                            throw new UnsupportedOperationException();
+                        }
+                    };
+                }
+            };
+        }
+
+        public Scope getOrigin(Symbol s) {
+            for (Scope.Entry e = lookup(s.name); e.scope != null ; e = e.next()) {
+                if (e.sym == s) {
+                    return this;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public boolean isStaticallyImported(Symbol s) {
+            return false;
+        }
+
+        public String toString() {
+            StringBuilder result = new StringBuilder();
+            result.append("Scope[");
+            for (ScopeImpl s = this; s != null ; s = s.next) {
+                if (s != this) result.append(" | ");
+                for (Entry e = s.elems; e != null; e = e.sibling) {
+                    if (e != s.elems) result.append(", ");
+                    result.append(e.sym);
+                }
+            }
+            result.append("]");
+            return result.toString();
+        }
     }
 
     /** A class for scope entries.
      */
-    public static class Entry {
+    private static class Entry {
 
         /** The referenced symbol.
          *  sym == null   iff   this == sentinel
@@ -475,8 +623,6 @@
 
         /** The entry's scope.
          *  scope == null   iff   this == sentinel
-         *  for an entry in an import scope, this is the scope
-         *  where the entry came from (i.e. was imported from).
          */
         public Scope scope;
 
@@ -495,101 +641,201 @@
         }
 
         public Entry next(Filter<Symbol> sf) {
-            if (shadowed.sym == null || sf.accepts(shadowed.sym)) return shadowed;
+            if (shadowed.sym == null || sf == null || sf.accepts(shadowed.sym)) return shadowed;
             else return shadowed.next(sf);
         }
 
-        public boolean isStaticallyImported() {
-            return false;
+    }
+
+    public static class NamedImportScope extends CompoundScope {
+
+        public NamedImportScope(Symbol owner, Scope currentFileScope) {
+            super(owner);
+            prependSubScope(currentFileScope);
         }
 
-        public Scope getOrigin() {
-            // The origin is only recorded for import scopes.  For all
-            // other scope entries, the "enclosing" type is available
-            // from other sources.  See Attr.visitSelect and
-            // Attr.visitIdent.  Rather than throwing an assertion
-            // error, we return scope which will be the same as origin
-            // in many cases.
-            return scope;
+        public void importByName(Scope delegate, Scope origin, Name name, ImportFilter filter) {
+            appendScope(new FilterImportScope(delegate, origin, name, filter, true));
+        }
+
+        public void importType(Scope delegate, Scope origin, Symbol sym) {
+            appendScope(new SingleEntryScope(delegate.owner, sym, origin));
+        }
+
+        private void appendScope(Scope newScope) {
+            List<Scope> existingScopes = this.subScopes.reverse();
+            subScopes = List.of(existingScopes.head);
+            subScopes = subScopes.prepend(newScope);
+            for (Scope s : existingScopes.tail) {
+                subScopes = subScopes.prepend(s);
+            }
+        }
+
+        private static class SingleEntryScope extends Scope {
+
+            private final Symbol sym;
+            private final List<Symbol> content;
+            private final Scope origin;
+
+            public SingleEntryScope(Symbol owner, Symbol sym, Scope origin) {
+                super(owner);
+                this.sym = sym;
+                this.content = List.of(sym);
+                this.origin = origin;
+            }
+
+            @Override
+            public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) {
+                return sf == null || sf.accepts(sym) ? content : Collections.<Symbol>emptyList();
+            }
+
+            @Override
+            public Iterable<Symbol> getSymbolsByName(Name name,
+                                                     Filter<Symbol> sf,
+                                                     LookupKind lookupKind) {
+                return sym.name == name &&
+                       (sf == null || sf.accepts(sym)) ? content : Collections.<Symbol>emptyList();
+            }
+
+            @Override
+            public Scope getOrigin(Symbol byName) {
+                return sym == byName ? origin : null;
+            }
+
+            @Override
+            public boolean isStaticallyImported(Symbol byName) {
+                return false;
+            }
+
         }
     }
 
-    public static class ImportScope extends Scope {
-
-        public ImportScope(Symbol owner) {
-            super(owner);
-        }
-
-        @Override
-        Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope,
-                final Scope origin, final boolean staticallyImported) {
-            return new Entry(sym, shadowed, sibling, scope) {
-                @Override
-                public Scope getOrigin() {
-                    return origin;
-                }
-
-                @Override
-                public boolean isStaticallyImported() {
-                    return staticallyImported;
-                }
-            };
-        }
-    }
-
-    public static class StarImportScope extends ImportScope implements ScopeListener {
+    public static class StarImportScope extends CompoundScope {
 
         public StarImportScope(Symbol owner) {
             super(owner);
         }
 
-        public void importAll (Scope fromScope) {
-            for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
-                if (e.sym.kind == Kinds.TYP && !includes(e.sym))
-                    enter(e.sym, fromScope);
+        public void importAll(Scope delegate,
+                              Scope origin,
+                              ImportFilter filter,
+                              boolean staticImport) {
+            for (Scope existing : subScopes) {
+                Assert.check(existing instanceof FilterImportScope);
+                FilterImportScope fis = (FilterImportScope) existing;
+                if (fis.delegate == delegate && fis.origin == origin &&
+                    fis.filter == filter && fis.staticImport == staticImport)
+                    return ; //avoid entering the same scope twice
             }
-            // Register to be notified when imported items are removed
-            fromScope.addScopeListener(this);
+            prependSubScope(new FilterImportScope(delegate, origin, null, filter, staticImport));
         }
 
-        public void symbolRemoved(Symbol sym, Scope s) {
-            remove(sym);
-        }
-        public void symbolAdded(Symbol sym, Scope s) { }
     }
 
-    /** An empty scope, into which you can't place anything.  Used for
-     *  the scope for a variable initializer.
-     */
-    public static class DelegatedScope extends Scope {
-        Scope delegatee;
-        public static final Entry[] emptyTable = new Entry[0];
+    public interface ImportFilter {
+        public boolean accepts(Scope origin, Symbol sym);
+    }
 
-        public DelegatedScope(Scope outer) {
-            super(outer, outer.owner, emptyTable);
-            delegatee = outer;
+    private static class FilterImportScope extends Scope {
+
+        private final Scope delegate;
+        private final Scope origin;
+        private final Name  filterName;
+        private final ImportFilter filter;
+        private final boolean staticImport;
+
+        public FilterImportScope(Scope delegate,
+                                 Scope origin,
+                                 Name  filterName,
+                                 ImportFilter filter,
+                                 boolean staticImport) {
+            super(delegate.owner);
+            this.delegate = delegate;
+            this.origin = origin;
+            this.filterName = filterName;
+            this.filter = filter;
+            this.staticImport = staticImport;
         }
-        public Scope dup() {
-            return new DelegatedScope(next);
+
+        @Override
+        public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) {
+            if (filterName != null)
+                return getSymbolsByName(filterName, sf, lookupKind);
+            return new FilteredIterable(delegate.getSymbols(sf, lookupKind));
         }
-        public Scope dupUnshared() {
-            return new DelegatedScope(next);
+
+        @Override
+        public Iterable<Symbol> getSymbolsByName(Name name,
+                                                 Filter<Symbol> sf,
+                                                 LookupKind lookupKind) {
+            if (filterName != null && filterName != name)
+                return Collections.emptyList();
+            return new FilteredIterable(delegate.getSymbolsByName(name, sf, lookupKind));
         }
-        public Scope leave() {
-            return next;
+
+        @Override
+        public Scope getOrigin(Symbol byName) {
+            return origin;
         }
-        public void enter(Symbol sym) {
-            // only anonymous classes could be put here
+
+        @Override
+        public boolean isStaticallyImported(Symbol byName) {
+            return staticImport;
         }
-        public void enter(Symbol sym, Scope s) {
-            // only anonymous classes could be put here
+
+        private class FilteredIterator implements Iterator<Symbol> {
+            private final Iterator<Symbol> delegate;
+            private Symbol next;
+
+            public FilteredIterator(Iterator<Symbol> delegate) {
+                this.delegate = delegate;
+                update();
+            }
+
+            void update() {
+                while (delegate.hasNext()) {
+                    if (filter.accepts(origin, next = delegate.next()))
+                        return;
+                }
+
+                next = null;
+            }
+
+            @Override
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            @Override
+            public Symbol next() {
+                Symbol result = next;
+
+                update();
+
+                return result;
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException("Not supported.");
+            }
+
         }
-        public void remove(Symbol sym) {
-            throw new AssertionError(sym);
+
+        private class FilteredIterable implements Iterable<Symbol> {
+
+            private final Iterable<Symbol> unfiltered;
+
+            public FilteredIterable(Iterable<Symbol> unfiltered) {
+                this.unfiltered = unfiltered;
+            }
+
+            @Override
+            public Iterator<Symbol> iterator() {
+                return new FilteredIterator(unfiltered.iterator());
+            }
         }
-        public Entry lookup(Name name) {
-            return delegatee.lookup(name);
-        }
+
     }
 
     /** A class scope adds capabilities to keep track of changes in related
@@ -600,16 +846,14 @@
      */
     public static class CompoundScope extends Scope implements ScopeListener {
 
-        public static final Entry[] emptyTable = new Entry[0];
-
-        private List<Scope> subScopes = List.nil();
+        List<Scope> subScopes = List.nil();
         private int mark = 0;
 
         public CompoundScope(Symbol owner) {
-            super(null, owner, emptyTable);
+            super(owner);
         }
 
-        public void addSubScope(Scope that) {
+        public void prependSubScope(Scope that) {
            if (that != null) {
                 subScopes = subScopes.prepend(that);
                 that.addScopeListener(this);
@@ -618,7 +862,7 @@
                     sl.symbolAdded(null, this); //propagate upwards in case of nested CompoundScopes
                 }
            }
-         }
+        }
 
         public void symbolAdded(Symbol sym, Scope s) {
             mark++;
@@ -653,12 +897,13 @@
         }
 
         @Override
-        public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
+        public Iterable<Symbol> getSymbols(final Filter<Symbol> sf,
+                                           final LookupKind lookupKind) {
             return new Iterable<Symbol>() {
                 public Iterator<Symbol> iterator() {
                     return new CompoundScopeIterator(subScopes) {
                         Iterator<Symbol> nextIterator(Scope s) {
-                            return s.getElements(sf).iterator();
+                            return s.getSymbols(sf, lookupKind).iterator();
                         }
                     };
                 }
@@ -666,18 +911,40 @@
         }
 
         @Override
-        public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
+        public Iterable<Symbol> getSymbolsByName(final Name name,
+                                                 final Filter<Symbol> sf,
+                                                 final LookupKind lookupKind) {
             return new Iterable<Symbol>() {
                 public Iterator<Symbol> iterator() {
                     return new CompoundScopeIterator(subScopes) {
                         Iterator<Symbol> nextIterator(Scope s) {
-                            return s.getElementsByName(name, sf).iterator();
+                            return s.getSymbolsByName(name, sf, lookupKind).iterator();
                         }
                     };
                 }
             };
         }
 
+        @Override
+        public Scope getOrigin(Symbol sym) {
+            for (Scope delegate : subScopes) {
+                if (delegate.includes(sym))
+                    return delegate.getOrigin(sym);
+            }
+
+            return null;
+        }
+
+        @Override
+        public boolean isStaticallyImported(Symbol sym) {
+            for (Scope delegate : subScopes) {
+                if (delegate.includes(sym))
+                    return delegate.isStaticallyImported(sym);
+            }
+
+            return false;
+        }
+
         abstract class CompoundScopeIterator implements Iterator<Symbol> {
 
             private Iterator<Symbol> currentIterator;
@@ -715,41 +982,21 @@
                 currentIterator = null;
             }
         }
-
-        @Override
-        public Entry lookup(Name name, Filter<Symbol> sf) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Scope dup(Symbol newOwner) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void remove(Symbol sym) {
-            throw new UnsupportedOperationException();
-        }
     }
 
     /** An error scope, for which the owner should be an error symbol. */
-    public static class ErrorScope extends Scope {
-        ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
+    public static class ErrorScope extends ScopeImpl {
+        ErrorScope(ScopeImpl next, Symbol errSymbol, Entry[] table) {
             super(next, /*owner=*/errSymbol, table);
         }
         public ErrorScope(Symbol errSymbol) {
             super(errSymbol);
         }
-        public Scope dup() {
-            return new ErrorScope(this, owner, table);
+        public WriteableScope dup(Symbol newOwner) {
+            return new ErrorScope(this, newOwner, table);
         }
-        public Scope dupUnshared() {
-            return new ErrorScope(this, owner, table.clone());
+        public WriteableScope dupUnshared(Symbol newOwner) {
+            return new ErrorScope(this, newOwner, table.clone());
         }
         public Entry lookup(Name name) {
             Entry e = super.lookup(name);
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jul 10 12:39:26 2014 -0700
@@ -33,19 +33,21 @@
 import javax.lang.model.element.*;
 import javax.tools.JavaFileObject;
 
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.comp.Attr;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.Name;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.code.TypeTag.FORALL;
 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 
 /** Root class for Java symbols. It contains subclasses
  *  for specific sorts of symbols, such as variables, methods and operators,
@@ -376,7 +378,7 @@
 
     /** If this is a class or package, its members, otherwise null.
      */
-    public Scope members() {
+    public WriteableScope members() {
         return null;
     }
 
@@ -475,15 +477,13 @@
         if (currentClass == owner) {
             return this;
         }
-        Scope.Entry e = currentClass.members().lookup(name);
-        while (e.scope != null) {
-            if (e.sym.kind == kind &&
+        for (Symbol sym : currentClass.members().getSymbolsByName(name)) {
+            if (sym.kind == kind &&
                     (kind != MTH ||
-                    (e.sym.flags() & STATIC) != 0 &&
-                    types.isSubSignature(e.sym.type, type))) {
-                return e.sym;
+                    (sym.flags() & STATIC) != 0 &&
+                    types.isSubSignature(sym.type, type))) {
+                return sym;
             }
-            e = e.next();
         }
         Symbol hiddenSym = null;
         for (Type st : types.interfaces(currentClass.type)
@@ -632,7 +632,7 @@
         public boolean isConstructor() { return other.isConstructor(); }
         public Name getQualifiedName() { return other.getQualifiedName(); }
         public Name flatName() { return other.flatName(); }
-        public Scope members() { return other.members(); }
+        public WriteableScope members() { return other.members(); }
         public boolean isInner() { return other.isInner(); }
         public boolean hasOuterInstance() { return other.hasOuterInstance(); }
         public ClassSymbol enclClass() { return other.enclClass(); }
@@ -721,9 +721,9 @@
             if (kind == TYP && type.hasTag(TYPEVAR)) {
                 return list;
             }
-            for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
-                if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
-                    list = list.prepend(e.sym);
+            for (Symbol sym : members().getSymbols(NON_RECURSIVE)) {
+                if (sym != null && (sym.flags() & SYNTHETIC) == 0 && sym.owner == this)
+                    list = list.prepend(sym);
             }
             return list;
         }
@@ -818,7 +818,7 @@
     public static class PackageSymbol extends TypeSymbol
         implements PackageElement {
 
-        public Scope members_field;
+        public WriteableScope members_field;
         public Name fullname;
         public ClassSymbol package_info; // see bug 6443073
 
@@ -845,7 +845,7 @@
             return name.isEmpty() && owner != null;
         }
 
-        public Scope members() {
+        public WriteableScope members() {
             if (completer != null) complete();
             return members_field;
         }
@@ -910,7 +910,7 @@
         /** a scope for all class members; variables, methods and inner classes
          *  type parameters are not part of this scope
          */
-        public Scope members_field;
+        public WriteableScope members_field;
 
         /** the fully qualified name of the class, i.e. pck.outer.inner.
          *  null for anonymous classes
@@ -971,7 +971,7 @@
             return flags_field;
         }
 
-        public Scope members() {
+        public WriteableScope members() {
             if (completer != null) complete();
             return members_field;
         }
@@ -1397,15 +1397,13 @@
 
         public Symbol implementedIn(TypeSymbol c, Types types) {
             Symbol impl = null;
-            for (Scope.Entry e = c.members().lookup(name);
-                 impl == null && e.scope != null;
-                 e = e.next()) {
-                if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
+            for (Symbol sym : c.members().getSymbolsByName(name)) {
+                if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
                     // FIXME: I suspect the following requires a
                     // subst() for a parametric return type.
                     types.isSameType(type.getReturnType(),
-                                     types.memberType(owner.type, e.sym).getReturnType())) {
-                    impl = e.sym;
+                                     types.memberType(owner.type, sym).getReturnType())) {
+                    impl = sym;
                 }
             }
             return impl;
@@ -1441,12 +1439,10 @@
          */
         public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
             for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
-                for (Scope.Entry e = c.members().lookup(name);
-                     e.scope != null;
-                     e = e.next()) {
-                    if (e.sym.kind == MTH &&
-                        ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
-                        return (MethodSymbol)e.sym;
+                for (Symbol sym : c.members().getSymbolsByName(name)) {
+                    if (sym.kind == MTH &&
+                        ((MethodSymbol)sym).binaryOverrides(this, origin, types))
+                        return (MethodSymbol)sym;
                 }
             }
             return null;
--- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Jul 10 12:39:26 2014 -0700
@@ -34,6 +34,7 @@
 import javax.tools.JavaFileObject;
 
 
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.Completer;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
@@ -396,7 +397,7 @@
         sym.completer = null;
         sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
         sym.erasure_field = type;
-        sym.members_field = new Scope(sym);
+        sym.members_field = WriteableScope.create(sym);
         type.typarams_field = List.nil();
         type.allparams_field = List.nil();
         type.supertype_field = annotationType;
@@ -466,7 +467,7 @@
 
         // Create class to hold all predefined constants and operations.
         predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
-        Scope scope = new Scope(predefClass);
+        WriteableScope scope = WriteableScope.create(predefClass);
         predefClass.members_field = scope;
 
         // Get the initial completer for Symbols from the ClassFinder
@@ -578,7 +579,7 @@
         ClassType arrayClassType = (ClassType)arrayClass.type;
         arrayClassType.supertype_field = objectType;
         arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
-        arrayClass.members_field = new Scope(arrayClass);
+        arrayClass.members_field = WriteableScope.create(arrayClass);
         lengthVar = new VarSymbol(
             PUBLIC | FINAL,
             names.length,
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1050,6 +1050,10 @@
         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
             return v.visitUnion(this, p);
         }
+
+        public Iterable<? extends Type> getAlternativeTypes() {
+            return alternatives_field;
+        }
     }
 
     // a clone of a ClassType that knows about the bounds of an intersection type.
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 10 12:39:26 2014 -0700
@@ -403,7 +403,7 @@
             }
 
             final ListBuffer<Symbol> abstracts = new ListBuffer<>();
-            for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) {
+            for (Symbol sym : membersCache.getSymbols(new DescriptorFilter(origin))) {
                 Type mtype = memberType(origin.type, sym);
                 if (abstracts.isEmpty() ||
                         (sym.name == abstracts.first().name &&
@@ -633,7 +633,7 @@
         Type descType = findDescriptorType(targets.head);
         ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
         csym.completer = null;
-        csym.members_field = new Scope(csym);
+        csym.members_field = WriteableScope.create(csym);
         MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
         csym.members_field.enter(instDescSym);
         Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym,
@@ -655,7 +655,7 @@
         Symbol descSym = findDescriptorSymbol(origin);
         CompoundScope members = membersClosure(origin.type, false);
         ListBuffer<Symbol> overridden = new ListBuffer<>();
-        outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) {
+        outer: for (Symbol m2 : members.getSymbolsByName(descSym.name, bridgeFilter)) {
             if (m2 == descSym) continue;
             else if (descSym.overrides(m2, origin, Types.this, false)) {
                 for (Symbol m3 : overridden) {
@@ -1312,7 +1312,8 @@
                 UndetVar undetvar = (UndetVar)t;
                 WildcardType wt = (WildcardType)s;
                 switch(wt.kind) {
-                    case UNBOUND: //similar to ? extends Object
+                    case UNBOUND:
+                        break;
                     case EXTENDS: {
                         Type bound = wildUpperBound(s);
                         undetvar.addBound(InferenceBound.UPPER, bound, this);
@@ -2289,7 +2290,7 @@
         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
                 syms.objectType : // error condition, recover
                 erasure(firstExplicitBound);
-        bc.members_field = new Scope(bc);
+        bc.members_field = WriteableScope.create(bc);
         return bc.type;
     }
 
@@ -2618,8 +2619,8 @@
     }
 
     public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) {
-        for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) {
-            if (msym.overrides(e.sym, origin, Types.this, true)) {
+        for (Symbol sym : syms.objectType.tsym.members().getSymbolsByName(msym.name)) {
+            if (msym.overrides(sym, origin, Types.this, true)) {
                 return true;
             }
         }
@@ -2679,12 +2680,10 @@
                 while (t.hasTag(TYPEVAR))
                     t = t.getUpperBound();
                 TypeSymbol c = t.tsym;
-                for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
-                     e.scope != null;
-                     e = e.next(implFilter)) {
-                    if (e.sym != null &&
-                             e.sym.overrides(ms, origin, Types.this, checkResult))
-                        return (MethodSymbol)e.sym;
+                for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) {
+                    if (sym != null &&
+                             sym.overrides(ms, origin, Types.this, checkResult))
+                        return (MethodSymbol)sym;
                 }
             }
             return null;
@@ -2741,11 +2740,11 @@
                     CompoundScope membersClosure = new CompoundScope(csym);
                     if (!skipInterface) {
                         for (Type i : interfaces(t)) {
-                            membersClosure.addSubScope(visit(i, skipInterface));
+                            membersClosure.prependSubScope(visit(i, skipInterface));
                         }
                     }
-                    membersClosure.addSubScope(visit(supertype(t), skipInterface));
-                    membersClosure.addSubScope(csym.members());
+                    membersClosure.prependSubScope(visit(supertype(t), skipInterface));
+                    membersClosure.prependSubScope(csym.members());
                     e = new Entry(skipInterface, membersClosure);
                     _map.put(csym, e);
                 }
@@ -2774,7 +2773,7 @@
     public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
         Filter<Symbol> filter = new MethodFilter(ms, site);
         List<MethodSymbol> candidates = List.nil();
-            for (Symbol s : membersClosure(site, false).getElements(filter)) {
+            for (Symbol s : membersClosure(site, false).getSymbols(filter)) {
                 if (!site.tsym.isInterface() && !s.owner.isInterface()) {
                     return List.of((MethodSymbol)s);
                 } else if (!candidates.contains(s)) {
--- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Thu Jul 10 12:39:26 2014 -0700
@@ -690,7 +690,7 @@
         Scope scope = targetContainerType.tsym.members();
         int nr_value_elems = 0;
         boolean error = false;
-        for(Symbol elm : scope.getElementsByName(names.value)) {
+        for(Symbol elm : scope.getSymbolsByName(names.value)) {
             nr_value_elems++;
 
             if (nr_value_elems == 1 &&
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jul 10 12:39:26 2014 -0700
@@ -37,6 +37,7 @@
 import com.sun.source.util.SimpleTreeVisitor;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.comp.Check.CheckContext;
@@ -618,14 +619,11 @@
         return newEnv;
     }
 
-    Scope copyScope(Scope sc) {
-        Scope newScope = new Scope(sc.owner);
+    WriteableScope copyScope(WriteableScope sc) {
+        WriteableScope newScope = WriteableScope.create(sc.owner);
         List<Symbol> elemsList = List.nil();
-        while (sc != null) {
-            for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) {
-                elemsList = elemsList.prepend(e.sym);
-            }
-            sc = sc.next;
+        for (Symbol sym : sc.getSymbols()) {
+            elemsList = elemsList.prepend(sym);
         }
         for (Symbol s : elemsList) {
             newScope.enter(s);
@@ -1140,12 +1138,12 @@
             // Block is a static or instance initializer;
             // let the owner of the environment be a freshly
             // created BLOCK-method.
-            final Env<AttrContext> localEnv =
-                env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
-            localEnv.info.scope.owner =
+            Symbol fakeOwner =
                 new MethodSymbol(tree.flags | BLOCK |
                     env.info.scope.owner.flags() & STRICTFP, names.empty, null,
                     env.info.scope.owner);
+            final Env<AttrContext> localEnv =
+                env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
 
             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
             attribStats(tree.stats, localEnv);
@@ -1328,7 +1326,7 @@
     }
     // where
         /** Add any variables defined in stats to the switch scope. */
-        private static void addVars(List<JCStatement> stats, Scope switchScope) {
+        private static void addVars(List<JCStatement> stats, WriteableScope switchScope) {
             for (;stats.nonEmpty(); stats = stats.tail) {
                 JCTree stat = stats.head;
                 if (stat.hasTag(VARDEF))
@@ -1344,10 +1342,9 @@
         }
         JCIdent ident = (JCIdent)tree;
         Name name = ident.name;
-        for (Scope.Entry e = enumType.tsym.members().lookup(name);
-             e.scope != null; e = e.next()) {
-            if (e.sym.kind == VAR) {
-                Symbol s = ident.sym = e.sym;
+        for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
+            if (sym.kind == VAR) {
+                Symbol s = ident.sym = sym;
                 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
                 ident.type = s.type;
                 return ((s.flags_field & Flags.ENUM) == 0)
@@ -2343,7 +2340,7 @@
                     Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym);
                     int count = 0;
                     boolean found = false;
-                    for (Symbol sym : csym.members().getElements()) {
+                    for (Symbol sym : csym.members().getSymbols()) {
                         if ((sym.flags() & SYNTHETIC) != 0 ||
                                 sym.isConstructor()) continue;
                         count++;
@@ -2774,15 +2771,15 @@
             Symbol owner = env.info.scope.owner;
             if (owner.kind == VAR && owner.owner.kind == TYP) {
                 //field initializer
-                lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared()));
                 ClassSymbol enclClass = owner.enclClass();
+                Symbol newScopeOwner = env.info.scope.owner;
                 /* if the field isn't static, then we can get the first constructor
                  * and use it as the owner of the environment. This is what
                  * LTM code is doing to look for type annotations so we are fine.
                  */
                 if ((owner.flags() & STATIC) == 0) {
-                    for (Symbol s : enclClass.members_field.getElementsByName(names.init)) {
-                        lambdaEnv.info.scope.owner = s;
+                    for (Symbol s : enclClass.members_field.getSymbolsByName(names.init)) {
+                        newScopeOwner = s;
                         break;
                     }
                 } else {
@@ -2798,8 +2795,9 @@
                         clinit.params = List.<VarSymbol>nil();
                         clinits.put(enclClass, clinit);
                     }
-                    lambdaEnv.info.scope.owner = clinit;
+                    newScopeOwner = clinit;
                 }
+                lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(newScopeOwner)));
             } else {
                 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
             }
@@ -4515,7 +4513,7 @@
 
         for (List<JCTypeParameter> l = tree.typarams;
              l.nonEmpty(); l = l.tail) {
-             Assert.checkNonNull(env.info.scope.lookup(l.head.name).scope);
+             Assert.checkNonNull(env.info.scope.findFirst(l.head.name));
         }
 
         // Check that a generic class doesn't extend Throwable
@@ -4602,16 +4600,21 @@
         private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) {
 
             // check for presence of serialVersionUID
-            Scope.Entry e = c.members().lookup(names.serialVersionUID);
-            while (e.scope != null && e.sym.kind != VAR) e = e.next();
-            if (e.scope == null) {
+            VarSymbol svuid = null;
+            for (Symbol sym : c.members().getSymbolsByName(names.serialVersionUID)) {
+                if (sym.kind == VAR) {
+                    svuid = (VarSymbol)sym;
+                    break;
+                }
+            }
+
+            if (svuid == null) {
                 log.warning(LintCategory.SERIAL,
                         tree.pos(), "missing.SVUID", c);
                 return;
             }
 
             // check that it is static final
-            VarSymbol svuid = (VarSymbol)e.sym;
             if ((svuid.flags() & (STATIC | FINAL)) !=
                 (STATIC | FINAL))
                 log.warning(LintCategory.SERIAL,
--- a/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/AttrContext.java	Thu Jul 10 12:39:26 2014 -0700
@@ -27,6 +27,7 @@
 
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 
 /** Contains information specific to the attribute and enter
  *  passes, to be used in place of the generic field in environments.
@@ -40,7 +41,7 @@
 
     /** The scope of local symbols.
      */
-    Scope scope = null;
+    WriteableScope scope = null;
 
     /** The number of enclosing `static' modifiers.
      */
@@ -87,7 +88,7 @@
 
     /** Duplicate this context, replacing scope field and copying all others.
      */
-    AttrContext dup(Scope scope) {
+    AttrContext dup(WriteableScope scope) {
         AttrContext info = new AttrContext();
         info.scope = scope;
         info.staticLevel = staticLevel;
@@ -112,7 +113,7 @@
     public Iterable<Symbol> getLocalElements() {
         if (scope == null)
             return List.nil();
-        return scope.getElements();
+        return scope.getSymbols();
     }
 
     boolean lastResolveVarargs() {
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 10 12:39:26 2014 -0700
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Attribute.Compound;
@@ -39,6 +40,8 @@
 
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Scope.NamedImportScope;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
@@ -51,6 +54,7 @@
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.code.TypeTag.WILDCARD;
 
@@ -362,16 +366,13 @@
      *  @param s             The scope.
      */
     void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
-        if (s.next != null) {
-            for (Scope.Entry e = s.next.lookup(v.name);
-                 e.scope != null && e.sym.owner == v.owner;
-                 e = e.next()) {
-                if (e.sym.kind == VAR &&
-                    (e.sym.owner.kind & (VAR | MTH)) != 0 &&
-                    v.name != names.error) {
-                    duplicateError(pos, e.sym);
-                    return;
-                }
+        for (Symbol sym : s.getSymbolsByName(v.name)) {
+            if (sym.owner != v.owner) break;
+            if (sym.kind == VAR &&
+                (sym.owner.kind & (VAR | MTH)) != 0 &&
+                v.name != names.error) {
+                duplicateError(pos, sym);
+                return;
             }
         }
     }
@@ -383,16 +384,13 @@
      *  @param s             The scope.
      */
     void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
-        if (s.next != null) {
-            for (Scope.Entry e = s.next.lookup(c.name);
-                 e.scope != null && e.sym.owner == c.owner;
-                 e = e.next()) {
-                if (e.sym.kind == TYP && !e.sym.type.hasTag(TYPEVAR) &&
-                    (e.sym.owner.kind & (VAR | MTH)) != 0 &&
-                    c.name != names.error) {
-                    duplicateError(pos, e.sym);
-                    return;
-                }
+        for (Symbol sym : s.getSymbolsByName(c.name)) {
+            if (sym.owner != c.owner) break;
+            if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
+                (sym.owner.kind & (VAR | MTH)) != 0 &&
+                c.name != names.error) {
+                duplicateError(pos, sym);
+                return;
             }
         }
     }
@@ -405,9 +403,9 @@
      *  @param s             The enclosing scope.
      */
     boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
-        for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
-            if (e.sym.kind == TYP && e.sym.name != names.error) {
-                duplicateError(pos, e.sym);
+        for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
+            if (sym.kind == TYP && sym.name != names.error) {
+                duplicateError(pos, sym);
                 return false;
             }
         }
@@ -1778,10 +1776,7 @@
         for (Type t1 = sup;
              t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
              t1 = types.supertype(t1)) {
-            for (Scope.Entry e1 = t1.tsym.members().elems;
-                 e1 != null;
-                 e1 = e1.sibling) {
-                Symbol s1 = e1.sym;
+            for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
                 if (s1.kind != MTH ||
                     (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
                     !s1.isInheritedIn(site.tsym, types) ||
@@ -1796,10 +1791,7 @@
                 for (Type t2 = sup;
                      t2.hasTag(CLASS);
                      t2 = types.supertype(t2)) {
-                    for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name);
-                         e2.scope != null;
-                         e2 = e2.next()) {
-                        Symbol s2 = e2.sym;
+                    for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
                         if (s2 == s1 ||
                             s2.kind != MTH ||
                             (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
@@ -1893,15 +1885,13 @@
 
     /** Return the first method in t2 that conflicts with a method from t1. */
     private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
-        for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
-            Symbol s1 = e1.sym;
+        for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
             Type st1 = null;
             if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
                     (s1.flags() & SYNTHETIC) != 0) continue;
             Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
             if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
-            for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {
-                Symbol s2 = e2.sym;
+            for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
                 if (s1 == s2) continue;
                 if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
                         (s2.flags() & SYNTHETIC) != 0) continue;
@@ -1944,8 +1934,7 @@
         Type st2 = types.memberType(site, s2);
         closure(site, supertypes);
         for (Type t : supertypes.values()) {
-            for (Scope.Entry e = t.tsym.members().lookup(s1.name); e.scope != null; e = e.next()) {
-                Symbol s3 = e.sym;
+            for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) {
                 if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
                 Type st3 = types.memberType(site,s3);
                 if (types.overrideEquivalent(st3, st1) &&
@@ -1995,14 +1984,12 @@
 
     void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
         TypeSymbol c = site.tsym;
-        Scope.Entry e = c.members().lookup(m.name);
-        while (e.scope != null) {
-            if (m.overrides(e.sym, origin, types, false)) {
-                if ((e.sym.flags() & ABSTRACT) == 0) {
-                    checkOverride(tree, m, (MethodSymbol)e.sym, origin);
+        for (Symbol sym : c.members().getSymbolsByName(m.name)) {
+            if (m.overrides(sym, origin, types, false)) {
+                if ((sym.flags() & ABSTRACT) == 0) {
+                    checkOverride(tree, m, (MethodSymbol)sym, origin);
                 }
             }
-            e = e.next();
         }
     }
 
@@ -2037,9 +2024,9 @@
             ClassSymbol someClass) {
         if (lint.isEnabled(LintCategory.OVERRIDES)) {
             MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
-                    .tsym.members().lookup(names.equals).sym;
+                    .tsym.members().findFirst(names.equals);
             MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
-                    .tsym.members().lookup(names.hashCode).sym;
+                    .tsym.members().findFirst(names.hashCode);
             boolean overridesEquals = types.implementation(equalsAtObject,
                 someClass, false, equalsHasCodeFilter).owner == someClass;
             boolean overridesHashCode = types.implementation(hashCodeAtObject,
@@ -2095,12 +2082,10 @@
             // since they cannot have abstract members.
             if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
                 Scope s = c.members();
-                for (Scope.Entry e = s.elems;
-                     undef == null && e != null;
-                     e = e.sibling) {
-                    if (e.sym.kind == MTH &&
-                        (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
-                        MethodSymbol absmeth = (MethodSymbol)e.sym;
+                for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+                    if (sym.kind == MTH &&
+                        (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
+                        MethodSymbol absmeth = (MethodSymbol)sym;
                         MethodSymbol implmeth = absmeth.implementation(impl, types, true);
                         if (implmeth == null || implmeth == absmeth) {
                             //look for default implementations
@@ -2113,6 +2098,7 @@
                         }
                         if (implmeth == null || implmeth == absmeth) {
                             undef = absmeth;
+                            break;
                         }
                     }
                 }
@@ -2336,10 +2322,10 @@
             for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
                 ClassSymbol lc = (ClassSymbol)l.head.tsym;
                 if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
-                    for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) {
-                        if (e.sym.kind == MTH &&
-                            (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
-                            MethodSymbol absmeth = (MethodSymbol)e.sym;
+                    for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
+                        if (sym.kind == MTH &&
+                            (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
+                            MethodSymbol absmeth = (MethodSymbol)sym;
                             MethodSymbol implmeth = absmeth.implementation(origin, types, false);
                             if (implmeth != null && implmeth != absmeth &&
                                 (implmeth.owner.flags() & INTERFACE) ==
@@ -2382,15 +2368,15 @@
 
     void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
         for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
-            for (Scope.Entry e = ct.tsym.members().lookup(sym.name); e.scope == ct.tsym.members(); e = e.next()) {
+            for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
                 // VM allows methods and variables with differing types
-                if (sym.kind == e.sym.kind &&
-                    types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) &&
-                    sym != e.sym &&
-                    (sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) &&
-                    (sym.flags() & IPROXY) == 0 && (e.sym.flags() & IPROXY) == 0 &&
-                    (sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) {
-                    syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym);
+                if (sym.kind == sym2.kind &&
+                    types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
+                    sym != sym2 &&
+                    (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
+                    (sym.flags() & IPROXY) == 0 && (sym2.flags() & IPROXY) == 0 &&
+                    (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
+                    syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
                     return;
                 }
             }
@@ -2411,7 +2397,7 @@
 
         List<MethodSymbol> potentiallyAmbiguousList = List.nil();
         boolean overridesAny = false;
-        for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
+        for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
             if (!sym.overrides(m1, site.tsym, types, false)) {
                 if (m1 == sym) {
                     continue;
@@ -2429,7 +2415,7 @@
             }
 
             //...check each method m2 that is a member of 'site'
-            for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
+            for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
                 if (m2 == m1) continue;
                 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
                 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
@@ -2466,7 +2452,7 @@
     void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
         ClashFilter cf = new ClashFilter(site);
         //for each method m1 that is a member of 'site'...
-        for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
+        for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
             //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
             //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
             if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
@@ -2508,7 +2494,7 @@
 
     void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
         DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
-        for (Symbol m : types.membersClosure(site, false).getElements(dcf)) {
+        for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
             Assert.check(m.kind == MTH);
             List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
             if (prov.size() > 1) {
@@ -2772,11 +2758,11 @@
     void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
         for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
             Scope s = sup.tsym.members();
-            for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {
-                if (e.sym.kind == MTH &&
-                    (e.sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
-                    types.overrideEquivalent(m.type, e.sym.type))
-                    log.error(pos, "intf.annotation.member.clash", e.sym, sup);
+            for (Symbol sym : s.getSymbolsByName(m.name)) {
+                if (sym.kind == MTH &&
+                    (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
+                    types.overrideEquivalent(m.type, sym.type))
+                    log.error(pos, "intf.annotation.member.clash", sym, sup);
             }
         }
     }
@@ -2856,9 +2842,9 @@
     }
 
     private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
-        Scope.Entry e = container.members().lookup(names.value);
-        if (e.scope != null && e.sym.kind == MTH) {
-            MethodSymbol m = (MethodSymbol) e.sym;
+        Symbol sym = container.members().findFirst(names.value);
+        if (sym != null && sym.kind == MTH) {
+            MethodSymbol m = (MethodSymbol) sym;
             Type ret = m.getReturnType();
             if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
                 log.error(pos, "invalid.repeatable.annotation.value.return",
@@ -3003,7 +2989,7 @@
     private void validateDefault(Symbol container, DiagnosticPosition pos) {
         // validate that all other elements of containing type has defaults
         Scope scope = container.members();
-        for(Symbol elm : scope.getElements()) {
+        for(Symbol elm : scope.getSymbols()) {
             if (elm.name != names.value &&
                 elm.kind == Kinds.MTH &&
                 ((MethodSymbol)elm).defaultValue == null) {
@@ -3025,8 +3011,8 @@
             if (sup == owner.type)
                 continue; // skip "this"
             Scope scope = sup.tsym.members();
-            for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
-                if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
+            for (Symbol sym : scope.getSymbolsByName(m.name)) {
+                if (!sym.isStatic() && m.overrides(sym, owner, types, true))
                     return true;
             }
         }
@@ -3160,12 +3146,10 @@
         boolean isValid = true;
         // collect an inventory of the annotation elements
         Set<MethodSymbol> members = new LinkedHashSet<>();
-        for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
-                e != null;
-                e = e.sibling)
-            if (e.sym.kind == MTH && e.sym.name != names.clinit &&
-                    (e.sym.flags() & SYNTHETIC) == 0)
-                members.add((MethodSymbol) e.sym);
+        for (Symbol sym : a.annotationType.type.tsym.members().getSymbols(NON_RECURSIVE))
+            if (sym.kind == MTH && sym.name != names.clinit &&
+                    (sym.flags() & SYNTHETIC) == 0)
+                members.add((MethodSymbol) sym);
 
         // remove the ones that are assigned values
         for (JCTree arg : a.args) {
@@ -3293,8 +3277,7 @@
         }
         try {
             tsym.flags_field |= LOCKED;
-            for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
-                Symbol s = e.sym;
+            for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
                 if (s.kind != Kinds.MTH)
                     continue;
                 checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
@@ -3436,23 +3419,23 @@
         if (sym.type.isErroneous())
             return true;
         if (sym.owner.name == names.any) return false;
-        for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
-            if (sym != e.sym &&
-                    (e.sym.flags() & CLASH) == 0 &&
-                    sym.kind == e.sym.kind &&
+        for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
+            if (sym != byName &&
+                    (byName.flags() & CLASH) == 0 &&
+                    sym.kind == byName.kind &&
                     sym.name != names.error &&
                     (sym.kind != MTH ||
-                     types.hasSameArgs(sym.type, e.sym.type) ||
-                     types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
-                if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
-                    varargsDuplicateError(pos, sym, e.sym);
+                     types.hasSameArgs(sym.type, byName.type) ||
+                     types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
+                if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
+                    varargsDuplicateError(pos, sym, byName);
                     return true;
-                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, e.sym.type, false)) {
-                    duplicateErasureError(pos, sym, e.sym);
+                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
+                    duplicateErasureError(pos, sym, byName);
                     sym.flags_field |= CLASH;
                     return true;
                 } else {
-                    duplicateError(pos, e.sym);
+                    duplicateError(pos, byName);
                     return false;
                 }
             }
@@ -3471,47 +3454,50 @@
     /** Check that single-type import is not already imported or top-level defined,
      *  but make an exception for two single-type imports which denote the same type.
      *  @param pos           Position for error reporting.
+     *  @param toplevel      The file in which in the check is performed.
      *  @param sym           The symbol.
-     *  @param s             The scope
      */
-    boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s) {
-        return checkUniqueImport(pos, sym, s, false);
+    boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
+        return checkUniqueImport(pos, toplevel, sym, false);
     }
 
     /** Check that static single-type import is not already imported or top-level defined,
      *  but make an exception for two single-type imports which denote the same type.
      *  @param pos           Position for error reporting.
+     *  @param toplevel      The file in which in the check is performed.
      *  @param sym           The symbol.
-     *  @param s             The scope
      */
-    boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym, Scope s) {
-        return checkUniqueImport(pos, sym, s, true);
+    boolean checkUniqueStaticImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
+        return checkUniqueImport(pos, toplevel, sym, true);
     }
 
     /** Check that single-type import is not already imported or top-level defined,
      *  but make an exception for two single-type imports which denote the same type.
      *  @param pos           Position for error reporting.
+     *  @param toplevel      The file in which in the check is performed.
      *  @param sym           The symbol.
-     *  @param s             The scope.
      *  @param staticImport  Whether or not this was a static import
      */
-    private boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s, boolean staticImport) {
-        for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) {
+    private boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym, boolean staticImport) {
+        NamedImportScope namedImportScope = toplevel.namedImportScope;
+        WriteableScope topLevelScope = toplevel.toplevelScope;
+
+        for (Symbol byName : namedImportScope.getSymbolsByName(sym.name)) {
             // is encountered class entered via a class declaration?
-            boolean isClassDecl = e.scope == s;
-            if ((isClassDecl || sym != e.sym) &&
-                sym.kind == e.sym.kind &&
+            boolean isClassDecl = namedImportScope.getOrigin(byName) == topLevelScope;
+            if ((isClassDecl || sym != byName) &&
+                sym.kind == byName.kind &&
                 sym.name != names.error &&
-                (!staticImport || !e.isStaticallyImported())) {
-                if (!e.sym.type.isErroneous()) {
+                (!staticImport || !namedImportScope.isStaticallyImported(byName))) {
+                if (!byName.type.isErroneous()) {
                     if (!isClassDecl) {
                         if (staticImport)
-                            log.error(pos, "already.defined.static.single.import", e.sym);
+                            log.error(pos, "already.defined.static.single.import", byName);
                         else
-                        log.error(pos, "already.defined.single.import", e.sym);
+                        log.error(pos, "already.defined.single.import", byName);
                     }
-                    else if (sym != e.sym)
-                        log.error(pos, "already.defined.this.unit", e.sym);
+                    else if (sym != byName)
+                        log.error(pos, "already.defined.this.unit", byName);
                 }
                 return false;
             }
@@ -3610,4 +3596,68 @@
             }
         }
     }
+
+    public void checkImportsResolvable(final JCCompilationUnit toplevel) {
+        for (final JCImport imp : toplevel.getImports()) {
+            if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
+                continue;
+            final JCFieldAccess select = (JCFieldAccess) imp.qualid;
+            final Symbol origin;
+            if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
+                continue;
+
+            JavaFileObject prev = log.useSource(toplevel.sourcefile);
+            try {
+                TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
+                if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
+                    log.error(imp.pos(), "cant.resolve.location",
+                              KindName.STATIC,
+                              select.name, List.<Type>nil(), List.<Type>nil(),
+                              Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
+                              TreeInfo.symbol(select.selected).type);
+                }
+            } finally {
+                log.useSource(prev);
+            }
+        }
+    }
+
+    private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
+        if (tsym == null || !processed.add(tsym))
+            return false;
+
+            // also search through inherited names
+        if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
+            return true;
+
+        for (Type t : types.interfaces(tsym.type))
+            if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
+                return true;
+
+        for (Symbol sym : tsym.members().getSymbolsByName(name)) {
+            if (sym.isStatic() &&
+                staticImportAccessible(sym, packge) &&
+                sym.isMemberOf(origin, types)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    // is the sym accessible everywhere in packge?
+    public boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
+        int flags = (int)(sym.flags() & AccessFlags);
+        switch (flags) {
+        default:
+        case PUBLIC:
+            return true;
+        case PRIVATE:
+            return false;
+        case 0:
+        case PROTECTED:
+            return sym.packge() == packge;
+        }
+    }
+
 }
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jul 10 12:39:26 2014 -0700
@@ -376,9 +376,8 @@
                              ResultInfo resultInfo,
                              Annotate.PositionCreator creator) {
         final JCTree newTree = new TreeCopier<>(make).copy(tree);
-        Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared()));
+        Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
         speculativeEnv.info.isSpeculative = true;
-        speculativeEnv.info.scope.owner = env.info.scope.owner;
         Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
                 new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() {
             public boolean accepts(final JCDiagnostic d) {
@@ -517,13 +516,11 @@
                     }
                 }
                 if (!progress) {
-                    DeferredAttrContext dac = this;
-                    while (dac != emptyDeferredAttrContext) {
-                        if (dac.mode == AttrMode.SPECULATIVE) {
-                            //unsticking does not take place during overload
-                            break;
+                    if (insideOverloadPhase()) {
+                        for (DeferredAttrNode deferredNode: deferredAttrNodes) {
+                            deferredNode.dt.tree.type = Type.noType;
                         }
-                        dac = dac.parent;
+                        return;
                     }
                     //remove all variables that have already been instantiated
                     //from the list of stuck variables
@@ -539,6 +536,17 @@
                 }
             }
         }
+
+        private boolean insideOverloadPhase() {
+            DeferredAttrContext dac = this;
+            if (dac == emptyDeferredAttrContext) {
+                return false;
+            }
+            if (dac.mode == AttrMode.SPECULATIVE) {
+                return true;
+            }
+            return dac.parent.insideOverloadPhase();
+        }
     }
 
     /**
@@ -599,6 +607,8 @@
                             return false;
                         }
                     } else {
+                        Assert.check(!deferredAttrContext.insideOverloadPhase(),
+                                "attribution shouldn't be happening here");
                         ResultInfo instResultInfo =
                                 resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
                         dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Jul 10 12:39:26 2014 -0700
@@ -191,7 +191,7 @@
      */
     public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
         Env<AttrContext> localEnv =
-            env.dup(tree, env.info.dup(new Scope(tree.sym)));
+            env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
         localEnv.enclClass = tree;
         localEnv.outer = env;
         localEnv.info.isSelfCall = false;
@@ -207,9 +207,10 @@
         Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
         localEnv.toplevel = tree;
         localEnv.enclClass = predefClassDef;
-        tree.namedImportScope = new ImportScope(tree.packge);
+        tree.toplevelScope = WriteableScope.create(tree.packge);
+        tree.namedImportScope = new NamedImportScope(tree.packge, tree.toplevelScope);
         tree.starImportScope = new StarImportScope(tree.packge);
-        localEnv.info.scope = tree.namedImportScope;
+        localEnv.info.scope = tree.toplevelScope;
         localEnv.info.lint = lint;
         return localEnv;
     }
@@ -218,7 +219,7 @@
         Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
         localEnv.toplevel = tree;
         localEnv.enclClass = predefClassDef;
-        localEnv.info.scope = tree.namedImportScope;
+        localEnv.info.scope = tree.toplevelScope;
         localEnv.info.lint = lint;
         return localEnv;
     }
@@ -228,7 +229,7 @@
      *  where the local scope is for type variables, and the this and super symbol
      *  only, and members go into the class member scope.
      */
-    Scope enterScope(Env<AttrContext> env) {
+    WriteableScope enterScope(Env<AttrContext> env) {
         return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
             ? ((JCClassDecl) env.tree).sym.members_field
             : env.info.scope;
@@ -324,7 +325,7 @@
             c.flatname = names.fromString(tree.packge + "." + name);
             c.sourcefile = tree.sourcefile;
             c.completer = null;
-            c.members_field = new Scope(c);
+            c.members_field = WriteableScope.create(c);
             tree.packge.package_info = c;
         }
         classEnter(tree.defs, topEnv);
@@ -338,7 +339,7 @@
     @Override
     public void visitClassDef(JCClassDecl tree) {
         Symbol owner = env.info.scope.owner;
-        Scope enclScope = enterScope(env);
+        WriteableScope enclScope = enterScope(env);
         ClassSymbol c;
         if (owner.kind == PCK) {
             // We are seeing a toplevel class.
@@ -392,7 +393,7 @@
         c.completer = memberEnter;
         c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
         c.sourcefile = env.toplevel.sourcefile;
-        c.members_field = new Scope(c);
+        c.members_field = WriteableScope.create(c);
 
         ClassType ct = (ClassType)c.type;
         if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
@@ -495,7 +496,7 @@
                 // if there remain any unimported toplevels (these must have
                 // no classes at all), process their import statements as well.
                 for (JCCompilationUnit tree : trees) {
-                    if (tree.starImportScope.elems == null) {
+                    if (tree.starImportScope.isEmpty()) {
                         JavaFileObject prev = log.useSource(tree.sourcefile);
                         Env<AttrContext> topEnv = topLevelEnv(tree);
                         memberEnter.memberEnter(tree, topEnv);
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Jul 10 12:39:26 2014 -0700
@@ -30,6 +30,7 @@
 import java.util.HashMap;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -1419,7 +1420,7 @@
 
         /** The list of unreferenced automatic resources.
          */
-        Scope unrefdResources;
+        WriteableScope unrefdResources;
 
         /** Set when processing a loop body the second time for DU analysis. */
         FlowKind flowKind = FlowKind.NORMAL;
@@ -2410,7 +2411,7 @@
                 nextadr = 0;
                 pendingExits = new ListBuffer<>();
                 this.classDef = null;
-                unrefdResources = new Scope(env.enclClass.sym);
+                unrefdResources = WriteableScope.create(env.enclClass.sym);
                 scan(tree);
             } finally {
                 // note that recursive invocations of this method fail hard
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Jul 10 12:39:26 2014 -0700
@@ -31,7 +31,7 @@
 import com.sun.tools.javac.tree.TreeTranslator;
 import com.sun.tools.javac.code.Attribute;
 import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
@@ -448,7 +448,7 @@
                 make.at(prevPos);
             }
             // Replace the entered symbol for this variable
-            Scope sc = tree.sym.owner.members();
+            WriteableScope sc = tree.sym.owner.members();
             if (sc != null) {
                 sc.remove(tree.sym);
                 sc.enter(xsym);
@@ -1475,7 +1475,7 @@
                 return clinit;
             } else {
                 //get the first constructor and treat it as the instance init sym
-                for (Symbol s : csym.members_field.getElementsByName(names.init)) {
+                for (Symbol s : csym.members_field.getSymbolsByName(names.init)) {
                     return s;
                 }
             }
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Jul 10 12:39:26 2014 -0700
@@ -28,6 +28,7 @@
 import java.util.*;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.main.Option.PkgInfo;
 import com.sun.tools.javac.tree.*;
@@ -45,6 +46,7 @@
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
@@ -299,7 +301,7 @@
             Symbol sym = _sym;
             if (sym.kind == VAR || sym.kind == MTH) {
                 while (sym != null && sym.owner != owner)
-                    sym = proxies.lookup(proxyName(sym.name)).sym;
+                    sym = proxies.findFirst(proxyName(sym.name));
                 if (sym != null && sym.owner == owner) {
                     VarSymbol v = (VarSymbol)sym;
                     if (v.getConstValue() == null) {
@@ -644,7 +646,7 @@
         }
         c.sourcefile = owner.sourcefile;
         c.completer = null;
-        c.members_field = new Scope(c);
+        c.members_field = WriteableScope.create(c);
         c.flags_field = flags;
         ClassType ctype = (ClassType) c.type;
         ctype.supertype_field = syms.objectType;
@@ -678,7 +680,7 @@
      *  @param sym           The symbol.
      *  @param s             The scope.
      */
-    private void enterSynthetic(DiagnosticPosition pos, Symbol sym, Scope s) {
+    private void enterSynthetic(DiagnosticPosition pos, Symbol sym, WriteableScope s) {
         s.enter(sym);
     }
 
@@ -746,7 +748,7 @@
      *  @param name         The name.
      */
     private Symbol lookupSynthetic(Name name, Scope s) {
-        Symbol sym = s.lookup(name).sym;
+        Symbol sym = s.findFirst(name);
         return (sym==null || (sym.flags()&SYNTHETIC)==0) ? null : sym;
     }
 
@@ -901,11 +903,9 @@
     /** Return binary operator that corresponds to given access code.
      */
     private OperatorSymbol binaryAccessOperator(int acode) {
-        for (Scope.Entry e = syms.predefClass.members().elems;
-             e != null;
-             e = e.sibling) {
-            if (e.sym instanceof OperatorSymbol) {
-                OperatorSymbol op = (OperatorSymbol)e.sym;
+        for (Symbol sym : syms.predefClass.members().getSymbols(NON_RECURSIVE)) {
+            if (sym instanceof OperatorSymbol) {
+                OperatorSymbol op = (OperatorSymbol)sym;
                 if (accessCode(op.opcode) == acode) return op;
             }
         }
@@ -1143,7 +1143,7 @@
                 return makeLit(sym.type, cv);
             }
             // Otherwise replace the variable by its proxy.
-            sym = proxies.lookup(proxyName(sym.name)).sym;
+            sym = proxies.findFirst(proxyName(sym.name));
             Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
             tree = make.at(tree.pos).Ident(sym);
         }
@@ -1459,12 +1459,12 @@
      *  in an additional innermost scope, where they represent the constructor
      *  parameters.
      */
-    Scope proxies;
+    WriteableScope proxies;
 
     /** A scope containing all unnamed resource variables/saved
      *  exception variables for translated TWR blocks
      */
-    Scope twrVars;
+    WriteableScope twrVars;
 
     /** A stack containing the this$n field of the currently translated
      *  classes (if needed) in innermost first order.
@@ -1519,7 +1519,7 @@
             nestingLevel++;
         }
         Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
-        while (owner.kind == TYP && ((ClassSymbol)owner).members().lookup(result).scope != null)
+        while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)
             result = names.fromString(result.toString() + target.syntheticNameChar());
         return result;
     }
@@ -1859,10 +1859,10 @@
      *  name is the name of a free variable.
      */
     JCStatement initField(int pos, Name name) {
-        Scope.Entry e = proxies.lookup(name);
-        Symbol rhs = e.sym;
+        Iterator<Symbol> it = proxies.getSymbolsByName(name).iterator();
+        Symbol rhs = it.next();
         Assert.check(rhs.owner.kind == MTH);
-        Symbol lhs = e.next().sym;
+        Symbol lhs = it.next();
         Assert.check(rhs.owner.owner == lhs.owner);
         make.at(pos);
         return
@@ -1903,10 +1903,10 @@
         if ((clazz.flags() & INTERFACE) == 0 &&
             !target.useInnerCacheClass()) return clazz;
         Scope s = clazz.members();
-        for (Scope.Entry e = s.elems; e != null; e = e.sibling)
-            if (e.sym.kind == TYP &&
-                e.sym.name == names.empty &&
-                (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym;
+        for (Symbol sym : s.getSymbols(NON_RECURSIVE))
+            if (sym.kind == TYP &&
+                sym.name == names.empty &&
+                (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
         return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
     }
 
@@ -2574,7 +2574,7 @@
 
         // private static final T[] #VALUES = { a, b, c };
         Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
-        while (tree.sym.members().lookup(valuesName).scope != null) // avoid name clash
+        while (tree.sym.members().findFirst(valuesName) != null) // avoid name clash
             valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
         Type arrayType = new ArrayType(types.erasure(tree.type),
                                        syms.arrayClass, Type.noAnnotations);
@@ -2602,7 +2602,7 @@
         } else {
             // template: T[] $result = new T[$values.length];
             Name resultName = names.fromString(target.syntheticNameChar() + "result");
-            while (tree.sym.members().lookup(resultName).scope != null) // avoid name clash
+            while (tree.sym.members().findFirst(resultName) != null) // avoid name clash
                 resultName = names.fromString(resultName + "" + target.syntheticNameChar());
             VarSymbol resultVar = new VarSymbol(FINAL|SYNTHETIC,
                                                 resultName,
@@ -2683,8 +2683,7 @@
         private MethodSymbol systemArraycopyMethod;
         private boolean useClone() {
             try {
-                Scope.Entry e = syms.objectType.tsym.members().lookup(names.clone);
-                return (e.sym != null);
+                return syms.objectType.tsym.members().findFirst(names.clone) != null;
             }
             catch (CompletionFailure e) {
                 return false;
@@ -2786,7 +2785,7 @@
                         final Name pName = proxyName(l.head.name);
                         m.capturedLocals =
                             m.capturedLocals.append((VarSymbol)
-                                                    (proxies.lookup(pName).sym));
+                                                    (proxies.findFirst(pName)));
                         added = added.prepend(
                           initField(tree.body.pos, pName));
                     }
@@ -3969,8 +3968,8 @@
             classdefs = new HashMap<>();
             actualSymbols = new HashMap<>();
             freevarCache = new HashMap<>();
-            proxies = new Scope(syms.noSymbol);
-            twrVars = new Scope(syms.noSymbol);
+            proxies = WriteableScope.create(syms.noSymbol);
+            twrVars = WriteableScope.create(syms.noSymbol);
             outerThisStack = List.nil();
             accessNums = new HashMap<>();
             accessSyms = new HashMap<>();
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Jul 10 12:39:26 2014 -0700
@@ -25,12 +25,18 @@
 
 package com.sun.tools.javac.comp;
 
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.IdentityHashMap;
 import java.util.Set;
 
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.ImportFilter;
+import com.sun.tools.javac.code.Scope.NamedImportScope;
+import com.sun.tools.javac.code.Scope.StarImportScope;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
@@ -43,6 +49,7 @@
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.code.TypeTag.ERROR;
 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
@@ -151,7 +158,7 @@
                            final TypeSymbol tsym,
                            Env<AttrContext> env) {
         // Check that packages imported from exist (JLS ???).
-        if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) {
+        if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
             // If we can't find java.lang, exit immediately.
             if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {
                 JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang");
@@ -160,7 +167,7 @@
                 log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym);
             }
         }
-        env.toplevel.starImportScope.importAll(tsym.members());
+        env.toplevel.starImportScope.importAll(tsym.members(), tsym.members(), typeImportFilter, false);
     }
 
     /** Import all static members of a class or package on demand.
@@ -171,82 +178,16 @@
     private void importStaticAll(int pos,
                                  final TypeSymbol tsym,
                                  Env<AttrContext> env) {
-        final JavaFileObject sourcefile = env.toplevel.sourcefile;
-        final Scope toScope = env.toplevel.starImportScope;
+        final StarImportScope toScope = env.toplevel.starImportScope;
         final PackageSymbol packge = env.toplevel.packge;
         final TypeSymbol origin = tsym;
 
         // enter imported types immediately
-        new Object() {
-            Set<Symbol> processed = new HashSet<>();
-            void importFrom(TypeSymbol tsym) {
-                if (tsym == null || !processed.add(tsym))
-                    return;
-
-                // also import inherited names
-                importFrom(types.supertype(tsym.type).tsym);
-                for (Type t : types.interfaces(tsym.type))
-                    importFrom(t.tsym);
-
-                final Scope fromScope = tsym.members();
-                for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
-                    Symbol sym = e.sym;
-                    if (sym.kind == TYP &&
-                        (sym.flags() & STATIC) != 0 &&
-                        staticImportAccessible(sym, packge) &&
-                        sym.isMemberOf(origin, types) &&
-                        !toScope.includes(sym))
-                        toScope.enter(sym, fromScope, origin.members(), true);
-                }
+        new SymbolImporter() {
+            void doImport(TypeSymbol tsym) {
+                toScope.importAll(tsym.members(), origin.members(), staticImportFilter, true);
             }
         }.importFrom(tsym);
-
-        // enter non-types before annotations that might use them
-        annotate.earlier(new Annotate.Worker() {
-            Set<Symbol> processed = new HashSet<>();
-
-            public String toString() {
-                return "import static " + tsym + ".*" + " in " + sourcefile;
-            }
-            void importFrom(TypeSymbol tsym) {
-                if (tsym == null || !processed.add(tsym))
-                    return;
-
-                // also import inherited names
-                importFrom(types.supertype(tsym.type).tsym);
-                for (Type t : types.interfaces(tsym.type))
-                    importFrom(t.tsym);
-
-                final Scope fromScope = tsym.members();
-                for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
-                    Symbol sym = e.sym;
-                    if (sym.isStatic() && sym.kind != TYP &&
-                        staticImportAccessible(sym, packge) &&
-                        !toScope.includes(sym) &&
-                        sym.isMemberOf(origin, types)) {
-                        toScope.enter(sym, fromScope, origin.members(), true);
-                    }
-                }
-            }
-            public void run() {
-                importFrom(tsym);
-            }
-        });
-    }
-
-    // is the sym accessible everywhere in packge?
-    boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
-        int flags = (int)(sym.flags() & AccessFlags);
-        switch (flags) {
-        default:
-        case PUBLIC:
-            return true;
-        case PRIVATE:
-            return false;
-        case 0:
-        case PROTECTED:
-            return sym.packge() == packge;
-        }
     }
 
     /** Import statics types of a given name.  Non-types are handled in Attr.
@@ -265,12 +206,46 @@
             return;
         }
 
-        final Scope toScope = env.toplevel.namedImportScope;
-        final PackageSymbol packge = env.toplevel.packge;
-        final TypeSymbol origin = tsym;
+        final NamedImportScope toScope = env.toplevel.namedImportScope;
+        final Scope originMembers = tsym.members();
 
         // enter imported types immediately
-        new Object() {
+        new SymbolImporter() {
+            void doImport(TypeSymbol tsym) {
+                Set<Symbol> maskedOut = null;
+                for (Symbol sym : tsym.members().getSymbolsByName(name)) {
+                    if (sym.kind == TYP &&
+                        staticImportFilter.accepts(originMembers, sym) &&
+                        !chk.checkUniqueStaticImport(pos, env.toplevel, sym)) {
+                        if (maskedOut == null)
+                            maskedOut = Collections.newSetFromMap(new IdentityHashMap<Symbol, Boolean>());
+                        maskedOut.add(sym);
+                    }
+                }
+                ImportFilter importFilter = maskedOut != null ?
+                        new MaskedImportFilter(staticImportFilter, maskedOut) :
+                        staticImportFilter;
+                toScope.importByName(tsym.members(), originMembers, name, importFilter);
+            }
+        }.importFrom(tsym);
+    }
+    //where:
+        class MaskedImportFilter implements ImportFilter {
+
+            private final ImportFilter delegate;
+            private final Set<Symbol> maskedOut;
+
+            public MaskedImportFilter(ImportFilter delegate, Set<Symbol> maskedOut) {
+                this.delegate = delegate;
+                this.maskedOut = maskedOut;
+            }
+
+            @Override
+            public boolean accepts(Scope origin, Symbol sym) {
+                return !maskedOut.contains(sym) && delegate.accepts(origin, sym);
+            }
+        }
+        abstract class SymbolImporter {
             Set<Symbol> processed = new HashSet<>();
             void importFrom(TypeSymbol tsym) {
                 if (tsym == null || !processed.add(tsym))
@@ -281,78 +256,21 @@
                 for (Type t : types.interfaces(tsym.type))
                     importFrom(t.tsym);
 
-                for (Scope.Entry e = tsym.members().lookup(name);
-                     e.scope != null;
-                     e = e.next()) {
-                    Symbol sym = e.sym;
-                    if (sym.isStatic() &&
-                        sym.kind == TYP &&
-                        staticImportAccessible(sym, packge) &&
-                        sym.isMemberOf(origin, types) &&
-                        chk.checkUniqueStaticImport(pos, sym, toScope))
-                        toScope.enter(sym, sym.owner.members(), origin.members(), true);
-                }
+                doImport(tsym);
             }
-        }.importFrom(tsym);
+            abstract void doImport(TypeSymbol tsym);
+        }
 
-        // enter non-types before annotations that might use them
-        annotate.earlier(new Annotate.Worker() {
-            Set<Symbol> processed = new HashSet<>();
-            boolean found = false;
-
-            public String toString() {
-                return "import static " + tsym + "." + name;
-            }
-            void importFrom(TypeSymbol tsym) {
-                if (tsym == null || !processed.add(tsym))
-                    return;
-
-                // also import inherited names
-                importFrom(types.supertype(tsym.type).tsym);
-                for (Type t : types.interfaces(tsym.type))
-                    importFrom(t.tsym);
-
-                for (Scope.Entry e = tsym.members().lookup(name);
-                     e.scope != null;
-                     e = e.next()) {
-                    Symbol sym = e.sym;
-                    if (sym.isStatic() &&
-                        staticImportAccessible(sym, packge) &&
-                        sym.isMemberOf(origin, types)) {
-                        found = true;
-                        if (sym.kind != TYP) {
-                            toScope.enter(sym, sym.owner.members(), origin.members(), true);
-                        }
-                    }
-                }
-            }
-            public void run() {
-                JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
-                try {
-                    importFrom(tsym);
-                    if (!found) {
-                        log.error(pos, "cant.resolve.location",
-                                  KindName.STATIC,
-                                  name, List.<Type>nil(), List.<Type>nil(),
-                                  Kinds.typeKindName(tsym.type),
-                                  tsym.type);
-                    }
-                } finally {
-                    log.useSource(prev);
-                }
-            }
-        });
-    }
     /** Import given class.
      *  @param pos           Position to be used for error reporting.
      *  @param tsym          The class to be imported.
      *  @param env           The environment containing the named import
      *                  scope to add to.
      */
-    private void importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env) {
+    private void importNamed(DiagnosticPosition pos, final Symbol tsym, Env<AttrContext> env) {
         if (tsym.kind == TYP &&
-            chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope))
-            env.toplevel.namedImportScope.enter(tsym, tsym.owner.members());
+            chk.checkUniqueImport(pos, env.toplevel, tsym))
+            env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym);
     }
 
     /** Construct method type from method signature.
@@ -482,6 +400,32 @@
  * Visitor methods for member enter
  *********************************************************************/
 
+    ImportFilter staticImportFilter;
+    ImportFilter typeImportFilter = new ImportFilter() {
+        @Override
+        public boolean accepts(Scope origin, Symbol t) {
+            return t.kind == Kinds.TYP;
+        }
+    };
+
+    protected void memberEnter(JCCompilationUnit tree, Env<AttrContext> env) {
+        ImportFilter prevStaticImportFilter = staticImportFilter;
+        try {
+            final PackageSymbol packge = env.toplevel.packge;
+            this.staticImportFilter = new ImportFilter() {
+                @Override
+                public boolean accepts(Scope origin, Symbol sym) {
+                    return sym.isStatic() &&
+                           chk.staticImportAccessible(sym, packge) &&
+                           sym.isMemberOf((TypeSymbol) origin.owner, types);
+                }
+            };
+            memberEnter((JCTree) tree, env);
+        } finally {
+            this.staticImportFilter = prevStaticImportFilter;
+        }
+    }
+
     /** Visitor argument: the current environment
      */
     protected Env<AttrContext> env;
@@ -570,7 +514,7 @@
     }
 
     public void visitTopLevel(JCCompilationUnit tree) {
-        if (tree.starImportScope.elems != null) {
+        if (!tree.starImportScope.isEmpty()) {
             // we must have already processed this toplevel
             return;
         }
@@ -640,7 +584,7 @@
     }
 
     public void visitMethodDef(JCMethodDecl tree) {
-        Scope enclScope = enter.enterScope(env);
+        WriteableScope enclScope = enter.enterScope(env);
         MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
         m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
         tree.sym = m;
@@ -696,9 +640,8 @@
      */
     Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {
         Env<AttrContext> localEnv =
-            env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
+            env.dup(tree, env.info.dup(env.info.scope.dupUnshared(tree.sym)));
         localEnv.enclMethod = tree;
-        localEnv.info.scope.owner = tree.sym;
         if (tree.sym.type != null) {
             //when this is called in the enter stage, there's no type to be set
             localEnv.info.returnResult = attr.new ResultInfo(VAL, tree.sym.type.getReturnType());
@@ -739,7 +682,7 @@
                 ArrayType atype = (ArrayType)tree.vartype.type;
                 tree.vartype.type = atype.makeVarargs();
             }
-            Scope enclScope = enter.enterScope(env);
+            WriteableScope enclScope = enter.enterScope(env);
             VarSymbol v =
                 new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
             v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
@@ -875,8 +818,7 @@
     Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {
         Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));
         if (tree.sym.owner.kind == TYP) {
-            localEnv.info.scope = env.info.scope.dupUnshared();
-            localEnv.info.scope.owner = tree.sym;
+            localEnv.info.scope = env.info.scope.dupUnshared(tree.sym);
         }
         if ((tree.mods.flags & STATIC) != 0 ||
                 ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null))
@@ -1220,23 +1162,30 @@
         // Enter all member fields and methods of a set of half completed
         // classes in a second phase.
         if (wasFirst) {
+            Set<JCCompilationUnit> topLevels = new HashSet<>();
             try {
                 while (halfcompleted.nonEmpty()) {
                     Env<AttrContext> toFinish = halfcompleted.next();
+                    topLevels.add(toFinish.toplevel);
                     finish(toFinish);
                 }
             } finally {
                 isFirst = true;
             }
+
+            for (JCCompilationUnit toplevel : topLevels) {
+                chk.checkImportsResolvable(toplevel);
+            }
+
         }
     }
 
     private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
-        Scope baseScope = new Scope(tree.sym);
+        WriteableScope baseScope = WriteableScope.create(tree.sym);
         //import already entered local classes into base scope
-        for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
-            if (e.sym.isLocal()) {
-                baseScope.enter(e.sym);
+        for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) {
+            if (sym.isLocal()) {
+                baseScope.enter(sym);
             }
         }
         //import current type-parameters into base scope
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jul 10 12:39:26 2014 -0700
@@ -28,6 +28,7 @@
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.tools.javac.api.Formattable.LocalizedString;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.comp.Attr.ResultInfo;
@@ -95,12 +96,12 @@
     public final boolean varargsEnabled;
     public final boolean allowMethodHandles;
     public final boolean allowFunctionalInterfaceMostSpecific;
-    public final boolean checkVarargsAccessDuringResolution;
+    public final boolean checkVarargsAccessAfterResolution;
     private final boolean debugResolve;
     private final boolean compactMethodDiags;
     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
 
-    Scope polymorphicSignatureScope;
+    WriteableScope polymorphicSignatureScope;
 
     protected Resolve(Context context) {
         context.put(resolveKey, this);
@@ -137,9 +138,9 @@
         Target target = Target.instance(context);
         allowMethodHandles = target.hasMethodHandles();
         allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
-        checkVarargsAccessDuringResolution =
+        checkVarargsAccessAfterResolution =
                 source.allowPostApplicabilityVarargsAccessCheck();
-        polymorphicSignatureScope = new Scope(syms.noSymbol);
+        polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
 
         inapplicableMethodException = new InapplicableMethodException(diags);
     }
@@ -836,13 +837,16 @@
                                     Warner warn) {
             super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
             //should we expand formals?
-            if ((!checkVarargsAccessDuringResolution ||
-                (checkVarargsAccessDuringResolution &&
-                 deferredAttrContext.mode == AttrMode.CHECK)) &&
-                deferredAttrContext.phase.isVarargsRequired()) {
-                //check varargs element type accessibility
-                varargsAccessible(env, types.elemtype(formals.last()),
-                        deferredAttrContext.inferenceContext);
+            if (deferredAttrContext.phase.isVarargsRequired()) {
+                Type typeToCheck = null;
+                if (!checkVarargsAccessAfterResolution) {
+                    typeToCheck = types.elemtype(formals.last());
+                } else if (deferredAttrContext.mode == AttrMode.CHECK) {
+                    typeToCheck = types.erasure(types.elemtype(formals.last()));
+                }
+                if (typeToCheck != null) {
+                    varargsAccessible(env, typeToCheck, deferredAttrContext.inferenceContext);
+                }
             }
         }
 
@@ -1296,13 +1300,11 @@
             c = c.type.getUpperBound().tsym;
         Symbol bestSoFar = varNotFound;
         Symbol sym;
-        Scope.Entry e = c.members().lookup(name);
-        while (e.scope != null) {
-            if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
-                return isAccessible(env, site, e.sym)
-                    ? e.sym : new AccessError(env, site, e.sym);
+        for (Symbol s : c.members().getSymbolsByName(name)) {
+            if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
+                return isAccessible(env, site, s)
+                    ? s : new AccessError(env, site, s);
             }
-            e = e.next();
         }
         Type st = types.supertype(c.type);
         if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
@@ -1345,20 +1347,20 @@
      */
     Symbol findVar(Env<AttrContext> env, Name name) {
         Symbol bestSoFar = varNotFound;
-        Symbol sym;
         Env<AttrContext> env1 = env;
         boolean staticOnly = false;
         while (env1.outer != null) {
+            Symbol sym = null;
             if (isStatic(env1)) staticOnly = true;
-            Scope.Entry e = env1.info.scope.lookup(name);
-            while (e.scope != null &&
-                   (e.sym.kind != VAR ||
-                    (e.sym.flags_field & SYNTHETIC) != 0))
-                e = e.next();
-            sym = (e.scope != null)
-                ? e.sym
-                : findField(
-                    env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
+            for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
+                if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
+                    sym = s;
+                    break;
+                }
+            }
+            if (sym == null) {
+                sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
+            }
             if (sym.exists()) {
                 if (staticOnly &&
                     sym.kind == VAR &&
@@ -1375,7 +1377,7 @@
             env1 = env1.outer;
         }
 
-        sym = findField(env, syms.predefClass.type, name, syms.predefClass);
+        Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
         if (sym.exists())
             return sym;
         if (bestSoFar.exists())
@@ -1383,18 +1385,16 @@
 
         Symbol origin = null;
         for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
-            Scope.Entry e = sc.lookup(name);
-            for (; e.scope != null; e = e.next()) {
-                sym = e.sym;
-                if (sym.kind != VAR)
+            for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
+                if (currentSymbol.kind != VAR)
                     continue;
                 // invariant: sym.kind == VAR
-                if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
-                    return new AmbiguityError(bestSoFar, sym);
+                if (bestSoFar.kind < AMBIGUOUS && currentSymbol.owner != bestSoFar.owner)
+                    return new AmbiguityError(bestSoFar, currentSymbol);
                 else if (bestSoFar.kind >= VAR) {
-                    origin = e.getOrigin().owner;
-                    bestSoFar = isAccessible(env, origin.type, sym)
-                        ? sym : new AccessError(env, origin.type, sym);
+                    origin = sc.getOrigin(currentSymbol).owner;
+                    bestSoFar = isAccessible(env, origin.type, currentSymbol)
+                        ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
                 }
             }
             if (bestSoFar.exists()) break;
@@ -1624,7 +1624,7 @@
             boolean useVarargs,
             boolean operator,
             boolean abstractok) {
-        for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) {
+        for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
             bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
                     bestSoFar, allowBoxing, useVarargs, operator);
         }
@@ -1824,12 +1824,11 @@
                    List<Type> argtypes, List<Type> typeargtypes,
                    boolean allowBoxing, boolean useVarargs) {
         Symbol bestSoFar = methodNotFound;
-        Symbol sym;
         Env<AttrContext> env1 = env;
         boolean staticOnly = false;
         while (env1.outer != null) {
             if (isStatic(env1)) staticOnly = true;
-            sym = findMethod(
+            Symbol sym = findMethod(
                 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
                 allowBoxing, useVarargs, false);
             if (sym.exists()) {
@@ -1845,41 +1844,37 @@
             env1 = env1.outer;
         }
 
-        sym = findMethod(env, syms.predefClass.type, name, argtypes,
-                         typeargtypes, allowBoxing, useVarargs, false);
+        Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
+                                typeargtypes, allowBoxing, useVarargs, false);
         if (sym.exists())
             return sym;
 
-        Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
-        for (; e.scope != null; e = e.next()) {
-            sym = e.sym;
-            Type origin = e.getOrigin().owner.type;
-            if (sym.kind == MTH) {
-                if (e.sym.owner.type != origin)
-                    sym = sym.clone(e.getOrigin().owner);
-                if (!isAccessible(env, origin, sym))
-                    sym = new AccessError(env, origin, sym);
-                bestSoFar = selectBest(env, origin,
+        for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
+            Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
+            if (currentSym.kind == MTH) {
+                if (currentSym.owner.type != origin.type)
+                    currentSym = currentSym.clone(origin);
+                if (!isAccessible(env, origin.type, currentSym))
+                    currentSym = new AccessError(env, origin.type, currentSym);
+                bestSoFar = selectBest(env, origin.type,
                                        argtypes, typeargtypes,
-                                       sym, bestSoFar,
+                                       currentSym, bestSoFar,
                                        allowBoxing, useVarargs, false);
             }
         }
         if (bestSoFar.exists())
             return bestSoFar;
 
-        e = env.toplevel.starImportScope.lookup(name);
-        for (; e.scope != null; e = e.next()) {
-            sym = e.sym;
-            Type origin = e.getOrigin().owner.type;
-            if (sym.kind == MTH) {
-                if (e.sym.owner.type != origin)
-                    sym = sym.clone(e.getOrigin().owner);
-                if (!isAccessible(env, origin, sym))
-                    sym = new AccessError(env, origin, sym);
-                bestSoFar = selectBest(env, origin,
+        for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
+            Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
+            if (currentSym.kind == MTH) {
+                if (currentSym.owner.type != origin.type)
+                    currentSym = currentSym.clone(origin);
+                if (!isAccessible(env, origin.type, currentSym))
+                    currentSym = new AccessError(env, origin.type, currentSym);
+                bestSoFar = selectBest(env, origin.type,
                                        argtypes, typeargtypes,
-                                       sym, bestSoFar,
+                                       currentSym, bestSoFar,
                                        allowBoxing, useVarargs, false);
             }
         }
@@ -1918,14 +1913,12 @@
                                    Type site,
                                    Name name,
                                    TypeSymbol c) {
-        Scope.Entry e = c.members().lookup(name);
-        while (e.scope != null) {
-            if (e.sym.kind == TYP) {
-                return isAccessible(env, site, e.sym)
-                    ? e.sym
-                    : new AccessError(env, site, e.sym);
+        for (Symbol sym : c.members().getSymbolsByName(name)) {
+            if (sym.kind == TYP) {
+                return isAccessible(env, site, sym)
+                    ? sym
+                    : new AccessError(env, site, sym);
             }
-            e = e.next();
         }
         return typeNotFound;
     }
@@ -1992,8 +1985,8 @@
      */
     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
         Symbol bestSoFar = typeNotFound;
-        for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
-            Symbol sym = loadClass(env, e.sym.flatName());
+        for (Symbol s : scope.getSymbolsByName(name)) {
+            Symbol sym = loadClass(env, s.flatName());
             if (bestSoFar.kind == TYP && sym.kind == TYP &&
                 bestSoFar != sym)
                 return new AmbiguityError(bestSoFar, sym);
@@ -2004,15 +1997,13 @@
     }
 
     Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
-        for (Scope.Entry e = env.info.scope.lookup(name);
-             e.scope != null;
-             e = e.next()) {
-            if (e.sym.kind == TYP) {
+        for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
+            if (sym.kind == TYP) {
                 if (staticOnly &&
-                    e.sym.type.hasTag(TYPEVAR) &&
-                    e.sym.owner.kind == TYP)
-                    return new StaticError(e.sym);
-                return e.sym;
+                    sym.type.hasTag(TYPEVAR) &&
+                    sym.owner.kind == TYP)
+                    return new StaticError(sym);
+                return sym;
             }
         }
         return typeNotFound;
@@ -2320,42 +2311,6 @@
     }
 
 /* ***************************************************************************
- *  Debugging
- ****************************************************************************/
-
-    /** print all scopes starting with scope s and proceeding outwards.
-     *  used for debugging.
-     */
-    public void printscopes(Scope s) {
-        while (s != null) {
-            if (s.owner != null)
-                System.err.print(s.owner + ": ");
-            for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
-                if ((e.sym.flags() & ABSTRACT) != 0)
-                    System.err.print("abstract ");
-                System.err.print(e.sym + " ");
-            }
-            System.err.println();
-            s = s.next;
-        }
-    }
-
-    void printscopes(Env<AttrContext> env) {
-        while (env.outer != null) {
-            System.err.println("------------------------------");
-            printscopes(env.info.scope);
-            env = env.outer;
-        }
-    }
-
-    public void printscopes(Type t) {
-        while (t.hasTag(CLASS)) {
-            printscopes(t.tsym.members());
-            t = types.supertype(t);
-        }
-    }
-
-/* ***************************************************************************
  *  Name resolution
  *  Naming conventions are as for symbol lookup
  *  Unlike the find... methods these methods will report access errors
@@ -2453,7 +2408,7 @@
                                             List<Type> argtypes) {
         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
                 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
-        for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
+        for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
             if (types.isSameType(mtype, sym.type)) {
                return sym;
             }
@@ -2626,14 +2581,11 @@
                               boolean allowBoxing,
                               boolean useVarargs) {
         Symbol bestSoFar = methodNotFound;
-        for (Scope.Entry e = site.tsym.members().lookup(names.init);
-             e.scope != null;
-             e = e.next()) {
-            final Symbol sym = e.sym;
+        for (final Symbol sym : site.tsym.members().getSymbolsByName(names.init)) {
             //- System.out.println(" e " + e.sym);
             if (sym.kind == MTH &&
                 (sym.flags_field & SYNTHETIC) == 0) {
-                    List<Type> oldParams = e.sym.type.hasTag(FORALL) ?
+                    List<Type> oldParams = sym.type.hasTag(FORALL) ?
                             ((ForAll)sym.type).tvars :
                             List.<Type>nil();
                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
@@ -3249,7 +3201,7 @@
 
         @Override
         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
-            Scope sc = new Scope(syms.arrayClass);
+            WriteableScope sc = WriteableScope.create(syms.arrayClass);
             MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
             arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
             sc.enter(arrayConstr);
@@ -3359,7 +3311,7 @@
         while (env1.outer != null) {
             if (isStatic(env1)) staticOnly = true;
             if (env1.enclClass.sym == c) {
-                Symbol sym = env1.info.scope.lookup(name).sym;
+                Symbol sym = env1.info.scope.findFirst(name);
                 if (sym != null) {
                     if (staticOnly) sym = new StaticError(sym);
                     return accessBase(sym, pos, env.enclClass.sym.type,
@@ -3446,7 +3398,7 @@
             while (env1 != null && env1.outer != null) {
                 if (isStatic(env1)) staticOnly = true;
                 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
-                    Symbol sym = env1.info.scope.lookup(name).sym;
+                    Symbol sym = env1.info.scope.findFirst(name);
                     if (sym != null) {
                         if (staticOnly) sym = new StaticError(sym);
                         return sym;
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Jul 10 12:39:26 2014 -0700
@@ -37,6 +37,7 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
 import static com.sun.tools.javac.code.TypeTag.VOID;
@@ -449,8 +450,8 @@
                     TypeSymbol i,
                     ClassSymbol origin,
                     ListBuffer<JCTree> bridges) {
-        for (Scope.Entry e = i.members().elems; e != null; e = e.sibling)
-            addBridgeIfNeeded(pos, e.sym, origin, bridges);
+        for (Symbol sym : i.members().getSymbols(NON_RECURSIVE))
+            addBridgeIfNeeded(pos, sym, origin, bridges);
         for (List<Type> l = types.interfaces(i.type); l.nonEmpty(); l = l.tail)
             addBridges(pos, l.head.tsym, origin, bridges);
     }
@@ -529,14 +530,12 @@
         }
 
         // Check that we do not introduce a name clash by erasing types.
-        for (Scope.Entry e = tree.sym.owner.members().lookup(tree.name);
-             e.sym != null;
-             e = e.next()) {
-            if (e.sym != tree.sym &&
-                types.isSameType(erasure(e.sym.type), tree.type)) {
+        for (Symbol sym : tree.sym.owner.members().getSymbolsByName(tree.name)) {
+            if (sym != tree.sym &&
+                types.isSameType(erasure(sym.type), tree.type)) {
                 log.error(tree.pos(),
                           "name.clash.same.erasure", tree.sym,
-                          e.sym);
+                          sym);
                 return;
             }
         }
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Jul 10 12:39:26 2014 -0700
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.file.BaseFileObject;
@@ -141,7 +142,7 @@
 
     /** The current scope where type variables are entered.
      */
-    protected Scope typevars;
+    protected WriteableScope typevars;
 
     /** The path name of the class file currently being read.
      */
@@ -231,7 +232,7 @@
 
         profile = Profile.instance(context);
 
-        typevars = new Scope(syms.noSymbol);
+        typevars = WriteableScope.create(syms.noSymbol);
 
         lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
 
@@ -832,9 +833,9 @@
     /** Find type variable with given name in `typevars' scope.
      */
     Type findTypeVar(Name name) {
-        Scope.Entry e = typevars.lookup(name);
-        if (e.scope != null) {
-            return e.sym.type;
+        Symbol s = typevars.findFirst(name);
+        if (s != null) {
+            return s.type;
         } else {
             if (readingClassAttr) {
                 // While reading the class attribute, the supertypes
@@ -1228,9 +1229,10 @@
 
         MethodType type = nt.uniqueType.type.asMethodType();
 
-        for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next())
-            if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type))
-                return (MethodSymbol)e.sym;
+        for (Symbol sym : scope.getSymbolsByName(nt.name)) {
+            if (sym.kind == MTH && isSameBinaryType(sym.type.asMethodType(), type))
+                return (MethodSymbol)sym;
+        }
 
         if (nt.name != names.init)
             // not a constructor
@@ -1769,10 +1771,7 @@
         MethodSymbol findAccessMethod(Type container, Name name) {
             CompletionFailure failure = null;
             try {
-                for (Scope.Entry e = container.tsym.members().lookup(name);
-                     e.scope != null;
-                     e = e.next()) {
-                    Symbol sym = e.sym;
+                for (Symbol sym : container.tsym.members().getSymbolsByName(name)) {
                     if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0)
                         return (MethodSymbol) sym;
                 }
@@ -1852,11 +1851,9 @@
             VarSymbol enumerator = null;
             CompletionFailure failure = null;
             try {
-                for (Scope.Entry e = enumTypeSym.members().lookup(proxy.enumerator);
-                     e.scope != null;
-                     e = e.next()) {
-                    if (e.sym.kind == VAR) {
-                        enumerator = (VarSymbol)e.sym;
+                for (Symbol sym : enumTypeSym.members().getSymbolsByName(proxy.enumerator)) {
+                    if (sym.kind == VAR) {
+                        enumerator = (VarSymbol)sym;
                         break;
                     }
                 }
@@ -2197,7 +2194,7 @@
         ClassType ct = (ClassType)c.type;
 
         // allocate scope for members
-        c.members_field = new Scope(c);
+        c.members_field = WriteableScope.create(c);
 
         // prepare type variable table
         typevars = typevars.dup(currentOwner);
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.jvm.UninitializedType.*;
 import static com.sun.tools.javac.main.Option.*;
@@ -1563,12 +1564,12 @@
         }
     }
 
-    void writeFields(Scope.Entry e) {
+    void writeFields(Scope s) {
         // process them in reverse sibling order;
         // i.e., process them in declaration order.
         List<VarSymbol> vars = List.nil();
-        for (Scope.Entry i = e; i != null; i = i.sibling) {
-            if (i.sym.kind == VAR) vars = vars.prepend((VarSymbol)i.sym);
+        for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+            if (sym.kind == VAR) vars = vars.prepend((VarSymbol)sym);
         }
         while (vars.nonEmpty()) {
             writeField(vars.head);
@@ -1576,11 +1577,11 @@
         }
     }
 
-    void writeMethods(Scope.Entry e) {
+    void writeMethods(Scope s) {
         List<MethodSymbol> methods = List.nil();
-        for (Scope.Entry i = e; i != null; i = i.sibling) {
-            if (i.sym.kind == MTH && (i.sym.flags() & HYPOTHETICAL) == 0)
-                methods = methods.prepend((MethodSymbol)i.sym);
+        for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+            if (sym.kind == MTH && (sym.flags() & HYPOTHETICAL) == 0)
+                methods = methods.prepend((MethodSymbol)sym);
         }
         while (methods.nonEmpty()) {
             writeMethod(methods.head);
@@ -1654,12 +1655,12 @@
             databuf.appendChar(pool.put(l.head.tsym));
         int fieldsCount = 0;
         int methodsCount = 0;
-        for (Scope.Entry e = c.members().elems; e != null; e = e.sibling) {
-            switch (e.sym.kind) {
+        for (Symbol sym : c.members().getSymbols(NON_RECURSIVE)) {
+            switch (sym.kind) {
             case VAR: fieldsCount++; break;
-            case MTH: if ((e.sym.flags() & HYPOTHETICAL) == 0) methodsCount++;
+            case MTH: if ((sym.flags() & HYPOTHETICAL) == 0) methodsCount++;
                       break;
-            case TYP: enterInner((ClassSymbol)e.sym); break;
+            case TYP: enterInner((ClassSymbol)sym); break;
             default : Assert.error();
             }
         }
@@ -1671,9 +1672,9 @@
         }
 
         databuf.appendChar(fieldsCount);
-        writeFields(c.members().elems);
+        writeFields(c.members());
         databuf.appendChar(methodsCount);
-        writeMethods(c.members().elems);
+        writeMethods(c.members());
 
         int acountIdx = beginAttrs();
         int acount = 0;
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Jul 10 12:39:26 2014 -0700
@@ -45,6 +45,7 @@
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.jvm.CRTFlags.*;
@@ -302,7 +303,7 @@
 
         if (!target.interfaceObjectOverridesBinaryCompatibility()) {
             if ((sym.owner.flags() & INTERFACE) != 0 &&
-                syms.objectType.tsym.members().lookup(sym.name).scope != null)
+                syms.objectType.tsym.members().findFirst(sym.name) != null)
                 return sym;
         }
 
@@ -651,13 +652,10 @@
     void implementInterfaceMethods(ClassSymbol c, ClassSymbol site) {
         for (List<Type> l = types.interfaces(c.type); l.nonEmpty(); l = l.tail) {
             ClassSymbol i = (ClassSymbol)l.head.tsym;
-            for (Scope.Entry e = i.members().elems;
-                 e != null;
-                 e = e.sibling)
-            {
-                if (e.sym.kind == MTH && (e.sym.flags() & STATIC) == 0)
+            for (Symbol sym : i.members().getSymbols(NON_RECURSIVE)) {
+                if (sym.kind == MTH && (sym.flags() & STATIC) == 0)
                 {
-                    MethodSymbol absMeth = (MethodSymbol)e.sym;
+                    MethodSymbol absMeth = (MethodSymbol)sym;
                     MethodSymbol implMeth = absMeth.binaryImplementation(site, types);
                     if (implMeth == null)
                         addAbstractMethod(site, absMeth);
--- a/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Thu Jul 10 12:39:26 2014 -0700
@@ -37,7 +37,6 @@
 
 import com.sun.tools.javac.code.Attribute;
 import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Scope;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
@@ -53,6 +52,7 @@
 
 import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 
 /** This class provides operations to write native header files for classes.
  *
@@ -146,8 +146,7 @@
         if (c.isLocal() || isSynthetic(c))
             return false;
 
-        for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
-            Symbol sym = i.sym;
+        for (Symbol sym : c.members_field.getSymbols(NON_RECURSIVE)) {
             if (sym.kind == MTH && isNative(sym))
                 return true;
             for (Attribute.Compound a: sym.getDeclarationAttributes()) {
@@ -156,8 +155,7 @@
             }
         }
         if (checkNestedClasses) {
-            for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
-                Symbol sym = i.sym;
+            for (Symbol sym : c.members_field.getSymbols(NON_RECURSIVE)) {
                 if ((sym.kind == TYP) && needsHeader(((ClassSymbol) sym), true))
                     return true;
             }
--- a/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -43,6 +43,7 @@
 import com.sun.tools.javac.code.Type.ArrayType;
 import com.sun.tools.javac.util.*;
 
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 
 /**
  * A generator of dynamic proxy implementations of
@@ -119,9 +120,9 @@
 
         // First find the default values.
         ClassSymbol sym = (ClassSymbol) anno.type.tsym;
-        for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
-            if (e.sym.kind == Kinds.MTH) {
-                MethodSymbol m = (MethodSymbol) e.sym;
+        for (Symbol s : sym.members().getSymbols(NON_RECURSIVE)) {
+            if (s.kind == Kinds.MTH) {
+                MethodSymbol m = (MethodSymbol) s;
                 Attribute def = m.getDefaultValue();
                 if (def != null)
                     res.put(m, def);
--- a/src/share/classes/com/sun/tools/javac/model/FilteredMemberList.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/FilteredMemberList.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -27,11 +27,12 @@
 
 import java.util.AbstractList;
 import java.util.Iterator;
-import java.util.NoSuchElementException;
 import com.sun.tools.javac.code.Scope;
 import com.sun.tools.javac.code.Symbol;
 
+import com.sun.tools.javac.util.Filter;
 import static com.sun.tools.javac.code.Flags.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 
 /**
  * Utility to construct a view of a symbol's members,
@@ -53,56 +54,28 @@
 
     public int size() {
         int cnt = 0;
-        for (Scope.Entry e = scope.elems; e != null; e = e.sibling) {
-            if (!unwanted(e.sym))
+        for (Symbol sym : scope.getSymbols(NON_RECURSIVE)) {
+            if (!unwanted(sym))
                 cnt++;
         }
         return cnt;
     }
 
     public Symbol get(int index) {
-        for (Scope.Entry e = scope.elems; e != null; e = e.sibling) {
-            if (!unwanted(e.sym) && (index-- == 0))
-                return e.sym;
+        for (Symbol sym : scope.getSymbols(NON_RECURSIVE)) {
+            if (!unwanted(sym) && (index-- == 0))
+                return sym;
         }
         throw new IndexOutOfBoundsException();
     }
 
     // A more efficient implementation than AbstractList's.
     public Iterator<Symbol> iterator() {
-        return new Iterator<Symbol>() {
-
-            /** The next entry to examine, or null if none. */
-            private Scope.Entry nextEntry = scope.elems;
-
-            private boolean hasNextForSure = false;
-
-            public boolean hasNext() {
-                if (hasNextForSure) {
-                    return true;
-                }
-                while (nextEntry != null && unwanted(nextEntry.sym)) {
-                    nextEntry = nextEntry.sibling;
-                }
-                hasNextForSure = (nextEntry != null);
-                return hasNextForSure;
+        return scope.getSymbols(new Filter<Symbol>() {
+            public boolean accepts(Symbol t) {
+                return !unwanted(t);
             }
-
-            public Symbol next() {
-                if (hasNext()) {
-                    Symbol result = nextEntry.sym;
-                    nextEntry = nextEntry.sibling;
-                    hasNextForSure = false;
-                    return result;
-                } else {
-                    throw new NoSuchElementException();
-                }
-            }
-
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
+        }, NON_RECURSIVE).iterator();
     }
 
     /**
--- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Jul 10 12:39:26 2014 -0700
@@ -35,6 +35,7 @@
 import static javax.lang.model.util.ElementFilter.methodsIn;
 
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Enter;
@@ -47,6 +48,7 @@
 import com.sun.tools.javac.tree.TreeScanner;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.Name;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
@@ -356,35 +358,31 @@
      */
     public FilteredMemberList getAllMembers(TypeElement element) {
         Symbol sym = cast(Symbol.class, element);
-        Scope scope = sym.members().dupUnshared();
+        WriteableScope scope = sym.members().dupUnshared();
         List<Type> closure = types.closure(sym.asType());
         for (Type t : closure)
             addMembers(scope, t);
         return new FilteredMemberList(scope);
     }
     // where
-        private void addMembers(Scope scope, Type type) {
+        private void addMembers(WriteableScope scope, Type type) {
             members:
-            for (Scope.Entry e = type.asElement().members().elems; e != null; e = e.sibling) {
-                Scope.Entry overrider = scope.lookup(e.sym.getSimpleName());
-                while (overrider.scope != null) {
-                    if (overrider.sym.kind == e.sym.kind
-                        && (overrider.sym.flags() & Flags.SYNTHETIC) == 0)
-                    {
-                        if (overrider.sym.getKind() == ElementKind.METHOD
-                        && overrides((ExecutableElement)overrider.sym, (ExecutableElement)e.sym, (TypeElement)type.asElement())) {
+            for (Symbol e : type.asElement().members().getSymbols(NON_RECURSIVE)) {
+                for (Symbol overrider : scope.getSymbolsByName(e.getSimpleName())) {
+                    if (overrider.kind == e.kind && (overrider.flags() & Flags.SYNTHETIC) == 0) {
+                        if (overrider.getKind() == ElementKind.METHOD &&
+                                overrides((ExecutableElement)overrider, (ExecutableElement)e, (TypeElement)type.asElement())) {
                             continue members;
                         }
                     }
-                    overrider = overrider.next();
                 }
-                boolean derived = e.sym.getEnclosingElement() != scope.owner;
-                ElementKind kind = e.sym.getKind();
+                boolean derived = e.getEnclosingElement() != scope.owner;
+                ElementKind kind = e.getKind();
                 boolean initializer = kind == ElementKind.CONSTRUCTOR
                     || kind == ElementKind.INSTANCE_INIT
                     || kind == ElementKind.STATIC_INIT;
-                if (!derived || (!initializer && e.sym.isInheritedIn(scope.owner, types)))
-                    scope.enter(e.sym);
+                if (!derived || (!initializer && e.isInheritedIn(scope.owner, types)))
+                    scope.enter(e);
             }
         }
 
--- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Thu Jul 10 12:39:26 2014 -0700
@@ -310,9 +310,9 @@
         for (Type t : types.closure(origin.type)) {
             if (t != origin.type) {
                 ClassSymbol c = (ClassSymbol) t.tsym;
-                for (Scope.Entry e = c.members().lookup(m.name); e.scope != null; e = e.next()) {
-                    if (e.sym.kind == Kinds.MTH && m.overrides(e.sym, origin, types, true)) {
-                        results.add((MethodSymbol) e.sym);
+                for (Symbol sym : c.members().getSymbolsByName(m.name)) {
+                    if (sym.kind == Kinds.MTH && m.overrides(sym, origin, types, true)) {
+                        results.add((MethodSymbol) sym);
                     }
                 }
             }
--- a/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -27,7 +27,7 @@
 
 import com.sun.tools.javac.api.JavacTaskImpl;
 import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Scope;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Attribute;
@@ -189,7 +189,7 @@
             new Attribute.Compound(syms.proprietaryType,
                                    List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
         Attribute.Compound[] profileAnnos = new Attribute.Compound[profiles.getProfileCount() + 1];
-        Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().lookup(names.value).sym;
+        Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().findFirst(names.value);
         for (int i = 1; i < profileAnnos.length; i++) {
             profileAnnos[i] = new Attribute.Compound(syms.profileType,
                     List.<Pair<Symbol.MethodSymbol, Attribute>>of(
@@ -259,9 +259,9 @@
             pool.reset();
             cs.pool = pool;
             writer.writeClass(cs);
-            for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) {
-                if (e.sym.kind == Kinds.TYP) {
-                    ClassSymbol nestedClass = (ClassSymbol)e.sym;
+            for (Symbol sym : cs.members().getSymbols(NON_RECURSIVE)) {
+                if (sym.kind == Kinds.TYP) {
+                    ClassSymbol nestedClass = (ClassSymbol)sym;
                     nestedClass.complete();
                     writeClass(pool, nestedClass, writer);
                 }
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -488,8 +488,10 @@
         public JavaFileObject sourcefile;
         /** The package to which this compilation unit belongs. */
         public PackageSymbol packge;
+        /** A scope containing top level classes. */
+        public WriteableScope toplevelScope;
         /** A scope for all named imports. */
-        public ImportScope namedImportScope;
+        public NamedImportScope namedImportScope;
         /** A scope for all import-on-demands. */
         public StarImportScope starImportScope;
         /** Line starting positions, defined only if option -g is set. */
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, 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
@@ -25,6 +25,8 @@
 
 package com.sun.tools.javac.tree;
 
+import java.util.Iterator;
+
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
@@ -692,13 +694,36 @@
             break;
         }
         case CLASS:
-            Type outer = t.getEnclosingType();
-            JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
-                ? Select(Type(outer), t.tsym)
-                : QualIdent(t.tsym);
-            tp = t.getTypeArguments().isEmpty()
-                ? clazz
-                : TypeApply(clazz, Types(t.getTypeArguments()));
+            switch (t.getKind()) {
+            case UNION: {
+                UnionClassType tu = (UnionClassType)t;
+                ListBuffer<JCExpression> la = new ListBuffer<>();
+                for (Type ta : tu.getAlternativeTypes()) {
+                    la.add(Type(ta));
+                }
+                tp = TypeUnion(la.toList());
+                break;
+            }
+            case INTERSECTION: {
+                IntersectionClassType it = (IntersectionClassType)t;
+                ListBuffer<JCExpression> la = new ListBuffer<>();
+                for (Type ta : it.getExplicitComponents()) {
+                    la.add(Type(ta));
+                }
+                tp = TypeIntersection(la.toList());
+                break;
+            }
+            default: {
+                Type outer = t.getEnclosingType();
+                JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
+                        ? Select(Type(outer), t.tsym)
+                        : QualIdent(t.tsym);
+                tp = t.getTypeArguments().isEmpty()
+                        ? clazz
+                        : TypeApply(clazz, Types(t.getTypeArguments()));
+                break;
+            }
+            }
             break;
         case ARRAY:
             tp = TypeArray(Type(types.elemtype(t)));
@@ -955,24 +980,26 @@
             sym.owner.kind == MTH || sym.owner.kind == VAR) {
             return true;
         } else if (sym.kind == TYP && toplevel != null) {
-            Scope.Entry e;
-            e = toplevel.namedImportScope.lookup(sym.name);
-            if (e.scope != null) {
+            Iterator<Symbol> it = toplevel.namedImportScope.getSymbolsByName(sym.name).iterator();
+            if (it.hasNext()) {
+                Symbol s = it.next();
                 return
-                  e.sym == sym &&
-                  e.next().scope == null;
+                  s == sym &&
+                  !it.hasNext();
             }
-            e = toplevel.packge.members().lookup(sym.name);
-            if (e.scope != null) {
+            it = toplevel.packge.members().getSymbolsByName(sym.name).iterator();
+            if (it.hasNext()) {
+                Symbol s = it.next();
                 return
-                  e.sym == sym &&
-                  e.next().scope == null;
+                  s == sym &&
+                  !it.hasNext();
             }
-            e = toplevel.starImportScope.lookup(sym.name);
-            if (e.scope != null) {
+            it = toplevel.starImportScope.getSymbolsByName(sym.name).iterator();
+            if (it.hasNext()) {
+                Symbol s = it.next();
                 return
-                  e.sym == sym &&
-                  e.next().scope == null;
+                  s == sym &&
+                  !it.hasNext();
             }
         }
         return false;
--- a/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -29,10 +29,12 @@
 
 import com.sun.source.util.TreePath;
 import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.util.List;
 
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+
 /**
  * Represents an annotation type.
  *
@@ -91,9 +93,9 @@
      */
     public AnnotationTypeElementDoc[] elements() {
         List<AnnotationTypeElementDoc> elements = List.nil();
-        for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null && e.sym.kind == Kinds.MTH) {
-                MethodSymbol s = (MethodSymbol)e.sym;
+        for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+            if (sym != null && sym.kind == Kinds.MTH) {
+                MethodSymbol s = (MethodSymbol)sym;
                 elements = elements.prepend(env.getAnnotationTypeElementDoc(s));
             }
         }
--- a/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java	Thu Jul 10 12:39:26 2014 -0700
@@ -59,6 +59,7 @@
 import com.sun.tools.javac.util.Names;
 import com.sun.tools.javac.util.Position;
 import static com.sun.tools.javac.code.Kinds.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
@@ -589,9 +590,9 @@
      */
     private FieldDoc[] fields(boolean filter, boolean enumConstants) {
         List<FieldDocImpl> fields = List.nil();
-        for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null && e.sym.kind == VAR) {
-                VarSymbol s = (VarSymbol)e.sym;
+        for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+            if (sym != null && sym.kind == VAR) {
+                VarSymbol s = (VarSymbol)sym;
                 boolean isEnum = ((s.flags() & Flags.ENUM) != 0) &&
                                  !env.legacyDoclet;
                 if (isEnum == enumConstants &&
@@ -614,12 +615,12 @@
     public MethodDoc[] methods(boolean filter) {
         Names names = tsym.name.table.names;
         List<MethodDocImpl> methods = List.nil();
-        for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null
-                && e.sym.kind == Kinds.MTH
-                && e.sym.name != names.init
-                && e.sym.name != names.clinit) {
-                MethodSymbol s = (MethodSymbol)e.sym;
+        for (Symbol sym :tsym.members().getSymbols(NON_RECURSIVE)) {
+            if (sym != null
+                && sym.kind == Kinds.MTH
+                && sym.name != names.init
+                && sym.name != names.clinit) {
+                MethodSymbol s = (MethodSymbol)sym;
                 if (!filter || env.shouldDocument(s)) {
                     methods = methods.prepend(env.getMethodDoc(s));
                 }
@@ -649,10 +650,10 @@
     public ConstructorDoc[] constructors(boolean filter) {
         Names names = tsym.name.table.names;
         List<ConstructorDocImpl> constructors = List.nil();
-        for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null &&
-                e.sym.kind == Kinds.MTH && e.sym.name == names.init) {
-                MethodSymbol s = (MethodSymbol)e.sym;
+        for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+            if (sym != null &&
+                sym.kind == Kinds.MTH && sym.name == names.init) {
+                MethodSymbol s = (MethodSymbol)sym;
                 if (!filter || env.shouldDocument(s)) {
                     constructors = constructors.prepend(env.getConstructorDoc(s));
                 }
@@ -685,10 +686,9 @@
             if (l.contains(this)) return;
             l.append(this);
             List<ClassDocImpl> more = List.nil();
-            for (Scope.Entry e = tsym.members().elems; e != null;
-                 e = e.sibling) {
-                if (e.sym != null && e.sym.kind == Kinds.TYP) {
-                    ClassSymbol s = (ClassSymbol)e.sym;
+            for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+                if (sym != null && sym.kind == Kinds.TYP) {
+                    ClassSymbol s = (ClassSymbol)sym;
                     ClassDocImpl c = env.getClassDoc(s);
                     if (c.isSynthetic()) continue;
                     if (c != null) more = more.prepend(c);
@@ -713,9 +713,9 @@
      */
     public ClassDoc[] innerClasses(boolean filter) {
         ListBuffer<ClassDocImpl> innerClasses = new ListBuffer<>();
-        for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null && e.sym.kind == Kinds.TYP) {
-                ClassSymbol s = (ClassSymbol)e.sym;
+        for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+            if (sym != null && sym.kind == Kinds.TYP) {
+                ClassSymbol s = (ClassSymbol)sym;
                 if ((s.flags_field & Flags.SYNTHETIC) != 0) continue;
                 if (!filter || env.isVisible(s)) {
                     innerClasses.prepend(env.getClassDoc(s));
@@ -809,17 +809,17 @@
             if (compenv == null) return null;
 
             Scope s = compenv.toplevel.namedImportScope;
-            for (Scope.Entry e = s.lookup(names.fromString(className)); e.scope != null; e = e.next()) {
-                if (e.sym.kind == Kinds.TYP) {
-                    ClassDoc c = env.getClassDoc((ClassSymbol)e.sym);
+            for (Symbol sym : s.getSymbolsByName(names.fromString(className))) {
+                if (sym.kind == Kinds.TYP) {
+                    ClassDoc c = env.getClassDoc((ClassSymbol)sym);
                     return c;
                 }
             }
 
             s = compenv.toplevel.starImportScope;
-            for (Scope.Entry e = s.lookup(names.fromString(className)); e.scope != null; e = e.next()) {
-                if (e.sym.kind == Kinds.TYP) {
-                    ClassDoc c = env.getClassDoc((ClassSymbol)e.sym);
+            for (Symbol sym : s.getSymbolsByName(names.fromString(className))) {
+                if (sym.kind == Kinds.TYP) {
+                    ClassDoc c = env.getClassDoc((ClassSymbol)sym);
                     return c;
                 }
             }
@@ -918,7 +918,6 @@
          *---------------------------------*/
 
         // search current class
-        Scope.Entry e = tsym.members().lookup(names.fromString(methodName));
 
         //### Using modifier filter here isn't really correct,
         //### but emulates the old behavior.  Instead, we should
@@ -931,11 +930,11 @@
             // In order to provide textually identical results, we
             // attempt to emulate the old behavior.
             MethodSymbol lastFound = null;
-            for (; e.scope != null; e = e.next()) {
-                if (e.sym.kind == Kinds.MTH) {
+            for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(methodName))) {
+                if (sym.kind == Kinds.MTH) {
                     //### Should intern methodName as Name.
-                    if (e.sym.name.toString().equals(methodName)) {
-                        lastFound = (MethodSymbol)e.sym;
+                    if (sym.name.toString().equals(methodName)) {
+                        lastFound = (MethodSymbol)sym;
                     }
                 }
             }
@@ -943,12 +942,12 @@
                 return env.getMethodDoc(lastFound);
             }
         } else {
-            for (; e.scope != null; e = e.next()) {
-                if (e.sym != null &&
-                    e.sym.kind == Kinds.MTH) {
+            for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(methodName))) {
+                if (sym != null &&
+                    sym.kind == Kinds.MTH) {
                     //### Should intern methodName as Name.
-                    if (hasParameterTypes((MethodSymbol)e.sym, paramTypes)) {
-                        return env.getMethodDoc((MethodSymbol)e.sym);
+                    if (hasParameterTypes((MethodSymbol)sym, paramTypes)) {
+                        return env.getMethodDoc((MethodSymbol)sym);
                     }
                 }
             }
@@ -1005,10 +1004,10 @@
     public ConstructorDoc findConstructor(String constrName,
                                           String[] paramTypes) {
         Names names = tsym.name.table.names;
-        for (Scope.Entry e = tsym.members().lookup(names.fromString("<init>")); e.scope != null; e = e.next()) {
-            if (e.sym.kind == Kinds.MTH) {
-                if (hasParameterTypes((MethodSymbol)e.sym, paramTypes)) {
-                    return env.getConstructorDoc((MethodSymbol)e.sym);
+        for (Symbol sym : tsym.members().getSymbolsByName(names.fromString("<init>"))) {
+            if (sym.kind == Kinds.MTH) {
+                if (hasParameterTypes((MethodSymbol)sym, paramTypes)) {
+                    return env.getConstructorDoc((MethodSymbol)sym);
                 }
             }
         }
@@ -1047,10 +1046,10 @@
         }
         searched.add(this);
 
-        for (Scope.Entry e = tsym.members().lookup(names.fromString(fieldName)); e.scope != null; e = e.next()) {
-            if (e.sym.kind == Kinds.VAR) {
+        for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(fieldName))) {
+            if (sym.kind == Kinds.VAR) {
                 //### Should intern fieldName as Name.
-                return env.getFieldDoc((VarSymbol)e.sym);
+                return env.getFieldDoc((VarSymbol)sym);
             }
         }
 
--- a/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -128,8 +128,8 @@
              t.hasTag(CLASS);
              t = env.types.supertype(t)) {
             ClassSymbol c = (ClassSymbol)t.tsym;
-            for (Scope.Entry e = c.members().lookup(sym.name); e.scope != null; e = e.next()) {
-                if (sym.overrides(e.sym, origin, env.types, true)) {
+            for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
+                if (sym.overrides(sym2, origin, env.types, true)) {
                     return TypeMaker.getType(env, t);
                 }
             }
@@ -160,9 +160,9 @@
              t.hasTag(CLASS);
              t = env.types.supertype(t)) {
             ClassSymbol c = (ClassSymbol)t.tsym;
-            for (Scope.Entry e = c.members().lookup(sym.name); e.scope != null; e = e.next()) {
-                if (sym.overrides(e.sym, origin, env.types, true)) {
-                    return env.getMethodDoc((MethodSymbol)e.sym);
+            for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
+                if (sym.overrides(sym2, origin, env.types, true)) {
+                    return env.getMethodDoc((MethodSymbol)sym2);
                 }
             }
         }
--- a/src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -33,7 +33,7 @@
 import com.sun.javadoc.*;
 import com.sun.source.util.TreePath;
 import com.sun.tools.javac.code.Attribute;
-import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.tree.JCTree;
@@ -43,6 +43,8 @@
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Position;
 
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+
 /**
  * Represents a java package.  Provides access to information
  * about the package, the package's comment and tags, and the
@@ -146,9 +148,9 @@
             return allClassesFiltered;
         }
         ListBuffer<ClassDocImpl> classes = new ListBuffer<>();
-        for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null) {
-                ClassSymbol s = (ClassSymbol)e.sym;
+        for (Symbol enumerated : sym.members().getSymbols(NON_RECURSIVE)) {
+            if (enumerated != null) {
+                ClassSymbol s = (ClassSymbol)enumerated;
                 ClassDocImpl c = env.getClassDoc(s);
                 if (c != null && !c.isSynthetic())
                     c.addAllClasses(classes, filtered);
--- a/src/share/classes/com/sun/tools/javadoc/SerializedForm.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/javadoc/SerializedForm.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,15 +26,13 @@
 package com.sun.tools.javadoc;
 
 import com.sun.javadoc.*;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
-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.util.*;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 
 /**
  * The serialized form is the specification of a class' serialization
@@ -159,9 +157,9 @@
         /* SERIALIZABLE_FIELDS can be private,
          * so must lookup by ClassSymbol, not by ClassDocImpl.
          */
-        for (Scope.Entry e = def.members().lookup(names.fromString(SERIALIZABLE_FIELDS)); e.scope != null; e = e.next()) {
-            if (e.sym.kind == Kinds.VAR) {
-                VarSymbol f = (VarSymbol)e.sym;
+        for (Symbol sym : def.members().getSymbolsByName(names.fromString(SERIALIZABLE_FIELDS))) {
+            if (sym.kind == Kinds.VAR) {
+                VarSymbol f = (VarSymbol)sym;
                 if ((f.flags() & Flags.STATIC) != 0 &&
                     (f.flags() & Flags.PRIVATE) != 0) {
                     return f;
@@ -180,9 +178,9 @@
     private void computeDefaultSerializableFields(DocEnv env,
                                                   ClassSymbol def,
                                                   ClassDocImpl cd) {
-        for (Scope.Entry e = def.members().elems; e != null; e = e.sibling) {
-            if (e.sym != null && e.sym.kind == Kinds.VAR) {
-                VarSymbol f = (VarSymbol)e.sym;
+        for (Symbol sym : def.members().getSymbols(NON_RECURSIVE)) {
+            if (sym != null && sym.kind == Kinds.VAR) {
+                VarSymbol f = (VarSymbol)sym;
                 if ((f.flags() & Flags.STATIC) == 0 &&
                     (f.flags() & Flags.TRANSIENT) == 0) {
                     //### No modifier filtering applied here.
@@ -209,9 +207,9 @@
     private void addMethodIfExist(DocEnv env, ClassSymbol def, String methodName) {
         Names names = def.name.table.names;
 
-        for (Scope.Entry e = def.members().lookup(names.fromString(methodName)); e.scope != null; e = e.next()) {
-            if (e.sym.kind == Kinds.MTH) {
-                MethodSymbol md = (MethodSymbol)e.sym;
+        for (Symbol sym : def.members().getSymbolsByName(names.fromString(methodName))) {
+            if (sym.kind == Kinds.MTH) {
+                MethodSymbol md = (MethodSymbol)sym;
                 if ((md.flags() & Flags.STATIC) == 0) {
                     /*
                      * WARNING: not robust if unqualifiedMethodName is overloaded
@@ -241,10 +239,9 @@
             Name fieldName = names.fromString(tag.fieldName());
 
             // Look for a FieldDocImpl that is documented by serialFieldTagImpl.
-            for (Scope.Entry e = def.members().lookup(fieldName);
-                 e.scope != null; e = e.next()) {
-                if (e.sym.kind == Kinds.VAR) {
-                    VarSymbol f = (VarSymbol) e.sym;
+            for (Symbol sym : def.members().getSymbolsByName(fieldName)) {
+                if (sym.kind == Kinds.VAR) {
+                    VarSymbol f = (VarSymbol) sym;
                     FieldDocImpl fdi = env.getFieldDoc(f);
                     ((SerialFieldTagImpl) (tag)).mapToFieldDocImpl(fdi);
                     break;
--- a/src/share/classes/com/sun/tools/jdeps/Analyzer.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/Analyzer.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,16 +26,13 @@
 
 import com.sun.tools.classfile.Dependency.Location;
 import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
-import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
 
 /**
  * Dependency Analyzer.
@@ -52,7 +49,16 @@
         VERBOSE
     }
 
+    /**
+     * Filter to be applied when analyzing the dependencies from the given archives.
+     * Only the accepted dependencies are recorded.
+     */
+    interface Filter {
+        boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive);
+    }
+
     private final Type type;
+    private final Filter filter;
     private final Map<Archive, ArchiveDeps> results = new HashMap<>();
     private final Map<Location, Archive> map = new HashMap<>();
     private final Archive NOT_FOUND
@@ -62,9 +68,11 @@
      * Constructs an Analyzer instance.
      *
      * @param type Type of the dependency analysis
+     * @param filter
      */
-    public Analyzer(Type type) {
+    public Analyzer(Type type, Filter filter) {
         this.type = type;
+        this.filter = filter;
     }
 
     /**
@@ -72,6 +80,18 @@
      */
     public void run(List<Archive> archives) {
         // build a map from Location to Archive
+        buildLocationArchiveMap(archives);
+
+        // traverse and analyze all dependencies
+        for (Archive archive : archives) {
+            ArchiveDeps deps = new ArchiveDeps(archive, type);
+            archive.visitDependences(deps);
+            results.put(archive, deps);
+        }
+    }
+
+    private void buildLocationArchiveMap(List<Archive> archives) {
+        // build a map from Location to Archive
         for (Archive archive: archives) {
             for (Location l: archive.getClasses()) {
                 if (!map.containsKey(l)) {
@@ -81,190 +101,202 @@
                 }
             }
         }
-        // traverse and analyze all dependencies
-        for (Archive archive : archives) {
-            ArchiveDeps deps;
-            if (type == Type.CLASS || type == Type.VERBOSE) {
-                deps = new ClassVisitor(archive);
-            } else {
-                deps = new PackageVisitor(archive);
-            }
-            archive.visitDependences(deps);
-            results.put(archive, deps);
-        }
     }
 
     public boolean hasDependences(Archive archive) {
         if (results.containsKey(archive)) {
-            return results.get(archive).deps.size() > 0;
+            return results.get(archive).dependencies().size() > 0;
         }
         return false;
     }
 
     public interface Visitor {
         /**
-         * Visits the source archive to its destination archive of
-         * a recorded dependency.
-         */
-        void visitArchiveDependence(Archive origin, Archive target, Profile profile);
-        /**
          * Visits a recorded dependency from origin to target which can be
-         * a fully-qualified classname, a package name, a profile or
+         * a fully-qualified classname, a package name, a module or
          * archive name depending on the Analyzer's type.
          */
-        void visitDependence(String origin, Archive source, String target, Archive archive, Profile profile);
+        public void visitDependence(String origin, Archive originArchive,
+                                    String target, Archive targetArchive);
     }
 
-    public void visitArchiveDependences(Archive source, Visitor v) {
-        ArchiveDeps r = results.get(source);
-        for (ArchiveDeps.Dep d: r.requireArchives()) {
-            v.visitArchiveDependence(r.archive, d.archive, d.profile);
+    /**
+     * Visit the dependencies of the given source.
+     * If the requested level is SUMMARY, it will visit the required archives list.
+     */
+    public void visitDependences(Archive source, Visitor v, Type level) {
+        if (level == Type.SUMMARY) {
+            final ArchiveDeps result = results.get(source);
+            result.requires().stream()
+                  .sorted(Comparator.comparing(Archive::getName))
+                  .forEach(archive -> {
+                      Profile profile = result.getTargetProfile(archive);
+                      v.visitDependence(source.getName(), source,
+                                        profile != null ? profile.profileName() : archive.getName(), archive);
+                  });
+        } else {
+            ArchiveDeps result = results.get(source);
+            if (level != type) {
+                // requesting different level of analysis
+                result = new ArchiveDeps(source, level);
+                source.visitDependences(result);
+            }
+            result.dependencies().stream()
+                  .sorted(Comparator.comparing(Dep::origin)
+                                    .thenComparing(Dep::target))
+                  .forEach(d -> v.visitDependence(d.origin(), d.originArchive(), d.target(), d.targetArchive()));
         }
     }
 
     public void visitDependences(Archive source, Visitor v) {
-        ArchiveDeps r = results.get(source);
-        for (Map.Entry<String, SortedSet<ArchiveDeps.Dep>> e: r.deps.entrySet()) {
-            String origin = e.getKey();
-            for (ArchiveDeps.Dep d: e.getValue()) {
-                // filter intra-dependency unless in verbose mode
-                if (type == Type.VERBOSE || d.archive != source) {
-                    v.visitDependence(origin, source, d.target, d.archive, d.profile);
+        visitDependences(source, v, type);
+    }
+
+    /**
+     * ArchiveDeps contains the dependencies for an Archive that can have one or
+     * more classes.
+     */
+    class ArchiveDeps implements Archive.Visitor {
+        protected final Archive archive;
+        protected final Set<Archive> requires;
+        protected final Set<Dep> deps;
+        protected final Type level;
+        private Profile profile;
+        ArchiveDeps(Archive archive, Type level) {
+            this.archive = archive;
+            this.deps = new HashSet<>();
+            this.requires = new HashSet<>();
+            this.level = level;
+        }
+
+        Set<Dep> dependencies() {
+            return deps;
+        }
+
+        Set<Archive> requires() {
+            return requires;
+        }
+
+        Profile getTargetProfile(Archive target) {
+            return JDKArchive.isProfileArchive(target) ? profile : null;
+        }
+
+        Archive findArchive(Location t) {
+            Archive target = archive.getClasses().contains(t) ? archive : map.get(t);
+            if (target == null) {
+                map.put(t, target = NOT_FOUND);
+            }
+            return target;
+        }
+
+        // return classname or package name depedning on the level
+        private String getLocationName(Location o) {
+            if (level == Type.CLASS || level == Type.VERBOSE) {
+                return o.getClassName();
+            } else {
+                String pkg = o.getPackageName();
+                return pkg.isEmpty() ? "<unnamed>" : pkg;
+            }
+        }
+
+        @Override
+        public void visit(Location o, Location t) {
+            Archive targetArchive = findArchive(t);
+            if (filter.accepts(o, archive, t, targetArchive)) {
+                addDep(o, t);
+                if (!requires.contains(targetArchive)) {
+                    requires.add(targetArchive);
+                }
+            }
+            if (targetArchive instanceof JDKArchive) {
+                Profile p = Profile.getProfile(t.getPackageName());
+                if (profile == null || (p != null && p.compareTo(profile) > 0)) {
+                    profile = p;
                 }
             }
         }
-    }
 
-    /**
-     * ArchiveDeps contains the dependencies for an Archive that
-     * can have one or more classes.
-     */
-    private abstract class ArchiveDeps implements Archive.Visitor {
-        final Archive archive;
-        final SortedMap<String, SortedSet<Dep>> deps;
-        ArchiveDeps(Archive archive) {
-            this.archive = archive;
-            this.deps = new TreeMap<>();
-        }
+        private Dep curDep;
+        protected Dep addDep(Location o, Location t) {
+            String origin = getLocationName(o);
+            String target = getLocationName(t);
+            Archive targetArchive = findArchive(t);
+            if (curDep != null &&
+                    curDep.origin().equals(origin) &&
+                    curDep.originArchive() == archive &&
+                    curDep.target().equals(target) &&
+                    curDep.targetArchive() == targetArchive) {
+                return curDep;
+            }
 
-        void add(String origin, String target, Archive targetArchive, String pkgName) {
-            SortedSet<Dep> set = deps.get(origin);
-            if (set == null) {
-                deps.put(origin, set = new TreeSet<>());
-            }
-            Profile p = targetArchive instanceof JDKArchive
-                            ? Profile.getProfile(pkgName) : null;
-            set.add(new Dep(target, targetArchive, p));
-        }
-
-        /**
-         * Returns the list of Archive dependences.  The returned
-         * list contains one {@code Dep} instance per one archive
-         * and with the minimum profile this archive depends on.
-         */
-        List<Dep> requireArchives() {
-            Map<Archive,Profile> map = new HashMap<>();
-            for (Set<Dep> set: deps.values()) {
-                for (Dep d: set) {
-                    if (this.archive != d.archive) {
-                        Profile p = map.get(d.archive);
-                        if (p == null || (d.profile != null && p.profile < d.profile.profile)) {
-                            map.put(d.archive, d.profile);
-                        }
+            Dep e = new Dep(origin, archive, target, targetArchive);
+            if (deps.contains(e)) {
+                for (Dep e1 : deps) {
+                    if (e.equals(e1)) {
+                        curDep = e1;
                     }
                 }
+            } else {
+                deps.add(e);
+                curDep = e;
             }
-            List<Dep> list = new ArrayList<>();
-            for (Map.Entry<Archive,Profile> e: map.entrySet()) {
-                list.add(new Dep("", e.getKey(), e.getValue()));
-            }
-            return list;
-        }
-
-        /**
-         * Dep represents a dependence where the target can be
-         * a classname or packagename and the archive and profile
-         * the target belongs to.
-         */
-        class Dep implements Comparable<Dep> {
-            final String target;
-            final Archive archive;
-            final Profile profile;
-            Dep(String target, Archive archive, Profile p) {
-                this.target = target;
-                this.archive = archive;
-                this.profile = p;
-            }
-
-            @Override
-            public boolean equals(Object o) {
-                if (o instanceof Dep) {
-                    Dep d = (Dep)o;
-                    return this.archive == d.archive && this.target.equals(d.target);
-                }
-                return false;
-            }
-
-            @Override
-            public int hashCode() {
-                int hash = 3;
-                hash = 17 * hash + Objects.hashCode(this.archive);
-                hash = 17 * hash + Objects.hashCode(this.target);
-                return hash;
-            }
-
-            @Override
-            public int compareTo(Dep o) {
-                if (this.target.equals(o.target)) {
-                    if (this.archive == o.archive) {
-                        return 0;
-                    } else {
-                        return this.archive.getFileName().compareTo(o.archive.getFileName());
-                    }
-                }
-                return this.target.compareTo(o.target);
-            }
-        }
-        public abstract void visit(Location o, Location t);
-    }
-
-    private class ClassVisitor extends ArchiveDeps {
-        ClassVisitor(Archive archive) {
-            super(archive);
-        }
-        @Override
-        public void visit(Location o, Location t) {
-            Archive targetArchive =
-                this.archive.getClasses().contains(t) ? this.archive : map.get(t);
-            if (targetArchive == null) {
-                map.put(t, targetArchive = NOT_FOUND);
-            }
-
-            String origin = o.getClassName();
-            String target = t.getClassName();
-            add(origin, target, targetArchive, t.getPackageName());
+            return curDep;
         }
     }
 
-    private class PackageVisitor extends ArchiveDeps {
-        PackageVisitor(Archive archive) {
-            super(archive);
+    /*
+     * Class-level or package-level dependency
+     */
+    class Dep {
+        final String origin;
+        final Archive originArchive;
+        final String target;
+        final Archive targetArchive;
+
+        Dep(String origin, Archive originArchive, String target, Archive targetArchive) {
+            this.origin = origin;
+            this.originArchive = originArchive;
+            this.target = target;
+            this.targetArchive = targetArchive;
         }
+
+        String origin() {
+            return origin;
+        }
+
+        Archive originArchive() {
+            return originArchive;
+        }
+
+        String target() {
+            return target;
+        }
+
+        Archive targetArchive() {
+            return targetArchive;
+        }
+
         @Override
-        public void visit(Location o, Location t) {
-            Archive targetArchive =
-                this.archive.getClasses().contains(t) ? this.archive : map.get(t);
-            if (targetArchive == null) {
-                map.put(t, targetArchive = NOT_FOUND);
+        @SuppressWarnings("unchecked")
+        public boolean equals(Object o) {
+            if (o instanceof Dep) {
+                Dep d = (Dep) o;
+                return this.origin.equals(d.origin) &&
+                        this.originArchive == d.originArchive &&
+                        this.target.equals(d.target) &&
+                        this.targetArchive == d.targetArchive;
             }
+            return false;
+        }
 
-            String origin = packageOf(o);
-            String target = packageOf(t);
-            add(origin, target, targetArchive, t.getPackageName());
-        }
-        public String packageOf(Location o) {
-            String pkg = o.getPackageName();
-            return pkg.isEmpty() ? "<unnamed>" : pkg;
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 67*hash + Objects.hashCode(this.origin)
+                           + Objects.hashCode(this.originArchive)
+                           + Objects.hashCode(this.target)
+                           + Objects.hashCode(this.targetArchive);
+            return hash;
         }
     }
 }
--- a/src/share/classes/com/sun/tools/jdeps/Archive.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/Archive.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -25,28 +25,34 @@
 package com.sun.tools.jdeps;
 
 import com.sun.tools.classfile.Dependency.Location;
+
+import java.io.IOException;
 import java.nio.file.Path;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Represents the source of the class files.
  */
 public class Archive {
+    public static Archive getInstance(Path p) throws IOException {
+        return new Archive(p, ClassFileReader.newInstance(p));
+    }
+
     private final Path path;
     private final String filename;
     private final ClassFileReader reader;
-    private final Map<Location, Set<Location>> deps = new HashMap<>();
+    protected Map<Location, Set<Location>> deps = new ConcurrentHashMap<>();
 
-    public Archive(String name) {
+    protected Archive(String name) {
         this.path = null;
         this.filename = name;
         this.reader = null;
     }
 
-    public Archive(Path p, ClassFileReader reader) {
+    protected Archive(Path p, ClassFileReader reader) {
         this.path = p;
         this.filename = path.getFileName().toString();
         this.reader = reader;
@@ -56,7 +62,7 @@
         return reader;
     }
 
-    public String getFileName() {
+    public String getName() {
         return filename;
     }
 
@@ -89,6 +95,10 @@
         }
     }
 
+    public boolean isEmpty() {
+        return getClasses().isEmpty();
+    }
+
     public String getPathName() {
         return path != null ? path.toString() : filename;
     }
--- a/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -68,7 +68,8 @@
 
     protected final Path path;
     protected final String baseFileName;
-    private ClassFileReader(Path path) {
+    protected final List<String> skippedEntries = new ArrayList<>();
+    protected ClassFileReader(Path path) {
         this.path = path;
         this.baseFileName = path.getFileName() != null
                                 ? path.getFileName().toString()
@@ -79,6 +80,10 @@
         return baseFileName;
     }
 
+    public List<String> skippedEntries() {
+        return skippedEntries;
+    }
+
     /**
      * Returns the ClassFile matching the given binary name
      * or a fully-qualified class name.
@@ -232,11 +237,12 @@
         }
     }
 
-    private static class JarFileReader extends ClassFileReader {
-        final JarFile jarfile;
+    static class JarFileReader extends ClassFileReader {
+        private final JarFile jarfile;
         JarFileReader(Path path) throws IOException {
-            this(path, new JarFile(path.toFile()));
+            this(path, new JarFile(path.toFile(), false));
         }
+
         JarFileReader(Path path, JarFile jf) throws IOException {
             super(path);
             this.jarfile = jf;
@@ -252,18 +258,18 @@
                             + entryName.substring(i + 1, entryName.length()));
                 }
                 if (e != null) {
-                    return readClassFile(e);
+                    return readClassFile(jarfile, e);
                 }
             } else {
                 JarEntry e = jarfile.getJarEntry(name + ".class");
                 if (e != null) {
-                    return readClassFile(e);
+                    return readClassFile(jarfile, e);
                 }
             }
             return null;
         }
 
-        private ClassFile readClassFile(JarEntry e) throws IOException {
+        protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException {
             InputStream is = null;
             try {
                 is = jarfile.getInputStream(e);
@@ -277,60 +283,76 @@
         }
 
         public Iterable<ClassFile> getClassFiles() throws IOException {
-            final Iterator<ClassFile> iter = new JarFileIterator();
+            final Iterator<ClassFile> iter = new JarFileIterator(this, jarfile);
             return new Iterable<ClassFile>() {
                 public Iterator<ClassFile> iterator() {
                     return iter;
                 }
             };
         }
+    }
 
-        class JarFileIterator implements Iterator<ClassFile> {
-            private Enumeration<JarEntry> entries;
-            private JarEntry nextEntry;
-            JarFileIterator() {
-                this.entries = jarfile.entries();
-                while (entries.hasMoreElements()) {
-                    JarEntry e = entries.nextElement();
-                    String name = e.getName();
-                    if (name.endsWith(".class")) {
-                        this.nextEntry = e;
-                        break;
-                    }
+    class JarFileIterator implements Iterator<ClassFile> {
+        protected final JarFileReader reader;
+        protected Enumeration<JarEntry> entries;
+        protected JarFile jf;
+        protected JarEntry nextEntry;
+        protected ClassFile cf;
+        JarFileIterator(JarFileReader reader) {
+            this(reader, null);
+        }
+        JarFileIterator(JarFileReader reader, JarFile jarfile) {
+            this.reader = reader;
+            setJarFile(jarfile);
+        }
+
+        void setJarFile(JarFile jarfile) {
+            if (jarfile == null) return;
+
+            this.jf = jarfile;
+            this.entries = jf.entries();
+            this.nextEntry = nextEntry();
+        }
+
+        public boolean hasNext() {
+            if (nextEntry != null && cf != null) {
+                return true;
+            }
+            while (nextEntry != null) {
+                try {
+                    cf = reader.readClassFile(jf, nextEntry);
+                    return true;
+                } catch (ClassFileError | IOException ex) {
+                    skippedEntries.add(nextEntry.getName());
+                }
+                nextEntry = nextEntry();
+            }
+            return false;
+        }
+
+        public ClassFile next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            ClassFile classFile = cf;
+            cf = null;
+            nextEntry = nextEntry();
+            return classFile;
+        }
+
+        protected JarEntry nextEntry() {
+            while (entries.hasMoreElements()) {
+                JarEntry e = entries.nextElement();
+                String name = e.getName();
+                if (name.endsWith(".class")) {
+                    return e;
                 }
             }
+            return null;
+        }
 
-            public boolean hasNext() {
-                return nextEntry != null;
-            }
-
-            public ClassFile next() {
-                if (!hasNext()) {
-                    throw new NoSuchElementException();
-                }
-
-                ClassFile cf;
-                try {
-                    cf = readClassFile(nextEntry);
-                } catch (IOException ex) {
-                    throw new ClassFileError(ex);
-                }
-                JarEntry entry = nextEntry;
-                nextEntry = null;
-                while (entries.hasMoreElements()) {
-                    JarEntry e = entries.nextElement();
-                    String name = e.getName();
-                    if (name.endsWith(".class")) {
-                        nextEntry = e;
-                        break;
-                    }
-                }
-                return cf;
-            }
-
-            public void remove() {
-                throw new UnsupportedOperationException("Not supported yet.");
-            }
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
         }
     }
 }
--- a/src/share/classes/com/sun/tools/jdeps/JdepsTask.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/JdepsTask.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -30,7 +30,9 @@
 import com.sun.tools.classfile.Dependencies;
 import com.sun.tools.classfile.Dependencies.ClassFileError;
 import com.sun.tools.classfile.Dependency;
+import com.sun.tools.classfile.Dependency.Location;
 import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
+import static com.sun.tools.jdeps.Analyzer.Type.*;
 import java.io.*;
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
@@ -110,7 +112,7 @@
             void process(JdepsTask task, String opt, String arg) throws BadArgs {
                 Path p = Paths.get(arg);
                 if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) {
-                    throw new BadArgs("err.dot.output.path", arg);
+                    throw new BadArgs("err.invalid.path", arg);
                 }
                 task.options.dotOutputDir = arg;
             }
@@ -118,25 +120,26 @@
         new Option(false, "-s", "-summary") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.showSummary = true;
-                task.options.verbose = Analyzer.Type.SUMMARY;
+                task.options.verbose = SUMMARY;
             }
         },
         new Option(false, "-v", "-verbose",
                           "-verbose:package",
-                          "-verbose:class")
-        {
+                          "-verbose:class") {
             void process(JdepsTask task, String opt, String arg) throws BadArgs {
                 switch (opt) {
                     case "-v":
                     case "-verbose":
-                        task.options.verbose = Analyzer.Type.VERBOSE;
+                        task.options.verbose = VERBOSE;
+                        task.options.filterSameArchive = false;
+                        task.options.filterSamePackage = false;
                         break;
                     case "-verbose:package":
-                            task.options.verbose = Analyzer.Type.PACKAGE;
-                            break;
+                        task.options.verbose = PACKAGE;
+                        break;
                     case "-verbose:class":
-                            task.options.verbose = Analyzer.Type.CLASS;
-                            break;
+                        task.options.verbose = CLASS;
+                        break;
                     default:
                         throw new BadArgs("err.invalid.arg.for.option", opt);
                 }
@@ -157,6 +160,32 @@
                 task.options.regex = arg;
             }
         },
+
+        new Option(true, "-f", "-filter") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.filterRegex = arg;
+            }
+        },
+        new Option(false, "-filter:package",
+                          "-filter:archive",
+                          "-filter:none") {
+            void process(JdepsTask task, String opt, String arg) {
+                switch (opt) {
+                    case "-filter:package":
+                        task.options.filterSamePackage = true;
+                        task.options.filterSameArchive = false;
+                        break;
+                    case "-filter:archive":
+                        task.options.filterSameArchive = true;
+                        task.options.filterSamePackage = false;
+                        break;
+                    case "-filter:none":
+                        task.options.filterSameArchive = false;
+                        task.options.filterSamePackage = false;
+                        break;
+                }
+            }
+        },
         new Option(true, "-include") {
             void process(JdepsTask task, String opt, String arg) throws BadArgs {
                 task.options.includePattern = Pattern.compile(arg);
@@ -178,12 +207,15 @@
         new Option(false, "-R", "-recursive") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.depth = 0;
+                // turn off filtering
+                task.options.filterSameArchive = false;
+                task.options.filterSamePackage = false;
             }
         },
         new Option(false, "-jdkinternals") {
             void process(JdepsTask task, String opt, String arg) {
                 task.options.findJDKInternals = true;
-                task.options.verbose = Analyzer.Type.CLASS;
+                task.options.verbose = CLASS;
                 if (task.options.includePattern == null) {
                     task.options.includePattern = Pattern.compile(".*");
                 }
@@ -262,7 +294,7 @@
                 showHelp();
                 return EXIT_CMDERR;
             }
-            if (options.showSummary && options.verbose != Analyzer.Type.SUMMARY) {
+            if (options.showSummary && options.verbose != SUMMARY) {
                 showHelp();
                 return EXIT_CMDERR;
             }
@@ -283,9 +315,28 @@
 
     private final List<Archive> sourceLocations = new ArrayList<>();
     private boolean run() throws IOException {
+        // parse classfiles and find all dependencies
         findDependencies();
-        Analyzer analyzer = new Analyzer(options.verbose);
+
+        Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() {
+            @Override
+            public boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive) {
+                if (options.findJDKInternals) {
+                    // accepts target that is JDK class but not exported
+                    return isJDKArchive(targetArchive) &&
+                              !((JDKArchive) targetArchive).isExported(target.getClassName());
+                } else if (options.filterSameArchive) {
+                    // accepts origin and target that from different archive
+                    return originArchive != targetArchive;
+                }
+                return true;
+            }
+        });
+
+        // analyze the dependencies
         analyzer.run(sourceLocations);
+
+        // output result
         if (options.dotOutputDir != null) {
             Path dir = Paths.get(options.dotOutputDir);
             Files.createDirectories(dir);
@@ -296,27 +347,34 @@
         return true;
     }
 
-    private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
+    private void generateSummaryDotFile(Path dir, Analyzer analyzer) throws IOException {
+        // If verbose mode (-v or -verbose option),
+        // the summary.dot file shows package-level dependencies.
+        Analyzer.Type summaryType =
+            (options.verbose == PACKAGE || options.verbose == SUMMARY) ? SUMMARY : PACKAGE;
         Path summary = dir.resolve("summary.dot");
-        boolean verbose = options.verbose == Analyzer.Type.VERBOSE;
-        DotGraph<?> graph = verbose ? new DotSummaryForPackage()
-                                    : new DotSummaryForArchive();
-        for (Archive archive : sourceLocations) {
-            analyzer.visitArchiveDependences(archive, graph);
-            if (verbose || options.showLabel) {
-                // traverse detailed dependences to generate package-level
-                // summary or build labels for edges
-                analyzer.visitDependences(archive, graph);
+        try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary));
+             SummaryDotFile dotfile = new SummaryDotFile(sw, summaryType)) {
+            for (Archive archive : sourceLocations) {
+                if (!archive.isEmpty()) {
+                    if (options.verbose == PACKAGE || options.verbose == SUMMARY) {
+                        if (options.showLabel) {
+                            // build labels listing package-level dependencies
+                            analyzer.visitDependences(archive, dotfile.labelBuilder(), PACKAGE);
+                        }
+                    }
+                    analyzer.visitDependences(archive, dotfile, summaryType);
+                }
             }
         }
-        try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary))) {
-            graph.writeTo(sw);
-        }
+    }
+
+    private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
         // output individual .dot file for each archive
-        if (options.verbose != Analyzer.Type.SUMMARY) {
+        if (options.verbose != SUMMARY) {
             for (Archive archive : sourceLocations) {
                 if (analyzer.hasDependences(archive)) {
-                    Path dotfile = dir.resolve(archive.getFileName() + ".dot");
+                    Path dotfile = dir.resolve(archive.getName() + ".dot");
                     try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile));
                          DotFileFormatter formatter = new DotFileFormatter(pw, archive)) {
                         analyzer.visitDependences(archive, formatter);
@@ -324,17 +382,23 @@
                 }
             }
         }
+        // generate summary dot file
+        generateSummaryDotFile(dir, analyzer);
     }
 
     private void printRawOutput(PrintWriter writer, Analyzer analyzer) {
+        RawOutputFormatter depFormatter = new RawOutputFormatter(writer);
+        RawSummaryFormatter summaryFormatter = new RawSummaryFormatter(writer);
         for (Archive archive : sourceLocations) {
-            RawOutputFormatter formatter = new RawOutputFormatter(writer);
-            analyzer.visitArchiveDependences(archive, formatter);
-            if (options.verbose != Analyzer.Type.SUMMARY) {
-                analyzer.visitDependences(archive, formatter);
+            if (!archive.isEmpty()) {
+                analyzer.visitDependences(archive, summaryFormatter, SUMMARY);
+                if (analyzer.hasDependences(archive) && options.verbose != SUMMARY) {
+                    analyzer.visitDependences(archive, depFormatter);
+                }
             }
         }
     }
+
     private boolean isValidClassName(String name) {
         if (!Character.isJavaIdentifierStart(name.charAt(0))) {
             return false;
@@ -348,21 +412,54 @@
         return true;
     }
 
-    private Dependency.Filter getDependencyFilter() {
-         if (options.regex != null) {
-            return Dependencies.getRegexFilter(Pattern.compile(options.regex));
-        } else if (options.packageNames.size() > 0) {
-            return Dependencies.getPackageFilter(options.packageNames, false);
-        } else {
-            return new Dependency.Filter() {
-                @Override
-                public boolean accepts(Dependency dependency) {
-                    return !dependency.getOrigin().equals(dependency.getTarget());
-                }
-            };
+    /*
+     * Dep Filter configured based on the input jdeps option
+     * 1. -p and -regex to match target dependencies
+     * 2. -filter:package to filter out same-package dependencies
+     *
+     * This filter is applied when jdeps parses the class files
+     * and filtered dependencies are not stored in the Analyzer.
+     *
+     * -filter:archive is applied later in the Analyzer as the
+     * containing archive of a target class may not be known until
+     * the entire archive
+     */
+    class DependencyFilter implements Dependency.Filter {
+        final Dependency.Filter filter;
+        final Pattern filterPattern;
+        DependencyFilter() {
+            if (options.regex != null) {
+                this.filter = Dependencies.getRegexFilter(Pattern.compile(options.regex));
+            } else if (options.packageNames.size() > 0) {
+                this.filter = Dependencies.getPackageFilter(options.packageNames, false);
+            } else {
+                this.filter = null;
+            }
+
+            this.filterPattern =
+                options.filterRegex != null ? Pattern.compile(options.filterRegex) : null;
+        }
+        @Override
+        public boolean accepts(Dependency d) {
+            if (d.getOrigin().equals(d.getTarget())) {
+                return false;
+            }
+            String pn = d.getTarget().getPackageName();
+            if (options.filterSamePackage && d.getOrigin().getPackageName().equals(pn)) {
+                return false;
+            }
+
+            if (filterPattern != null && filterPattern.matcher(pn).matches()) {
+                return false;
+            }
+            return filter != null ? filter.accepts(d) : true;
         }
     }
 
+    /**
+     * Tests if the given class matches the pattern given in the -include option
+     * or if it's a public class if -apionly option is specified
+     */
     private boolean matches(String classname, AccessFlags flags) {
         if (options.apiOnly && !flags.is(AccessFlags.ACC_PUBLIC)) {
             return false;
@@ -377,14 +474,14 @@
         Dependency.Finder finder =
             options.apiOnly ? Dependencies.getAPIFinder(AccessFlags.ACC_PROTECTED)
                             : Dependencies.getClassDependencyFinder();
-        Dependency.Filter filter = getDependencyFilter();
+        Dependency.Filter filter = new DependencyFilter();
 
         List<Archive> archives = new ArrayList<>();
         Deque<String> roots = new LinkedList<>();
         for (String s : classes) {
             Path p = Paths.get(s);
             if (Files.exists(p)) {
-                archives.add(new Archive(p, ClassFileReader.newInstance(p)));
+                archives.add(Archive.getInstance(p));
             } else {
                 if (isValidClassName(s)) {
                     roots.add(s);
@@ -421,19 +518,26 @@
                     throw new ClassFileError(e);
                 }
 
-                if (matches(classFileName, cf.access_flags)) {
-                    if (!doneClasses.contains(classFileName)) {
-                        doneClasses.add(classFileName);
+                // tests if this class matches the -include or -apiOnly option if specified
+                if (!matches(classFileName, cf.access_flags)) {
+                    continue;
+                }
+
+                if (!doneClasses.contains(classFileName)) {
+                    doneClasses.add(classFileName);
+                }
+
+                for (Dependency d : finder.findDependencies(cf)) {
+                    if (filter.accepts(d)) {
+                        String cn = d.getTarget().getName();
+                        if (!doneClasses.contains(cn) && !deque.contains(cn)) {
+                            deque.add(cn);
+                        }
+                        a.addClass(d.getOrigin(), d.getTarget());
                     }
-                    for (Dependency d : finder.findDependencies(cf)) {
-                        if (filter.accepts(d)) {
-                            String cn = d.getTarget().getName();
-                            if (!doneClasses.contains(cn) && !deque.contains(cn)) {
-                                deque.add(cn);
-                            }
-                            a.addClass(d.getOrigin(), d.getTarget());
-                        }
-                    }
+                }
+                for (String name : a.reader().skippedEntries()) {
+                    warning("warn.skipped.entry", name, a.getPathName());
                 }
             }
         }
@@ -462,6 +566,10 @@
                             // if name is a fully-qualified class name specified
                             // from command-line, this class might already be parsed
                             doneClasses.add(classFileName);
+                            // process @jdk.Exported for JDK classes
+                            if (isJDKArchive(a)) {
+                                ((JDKArchive)a).processJdkExported(cf);
+                            }
                             for (Dependency d : finder.findDependencies(cf)) {
                                 if (depth == 0) {
                                     // ignore the dependency
@@ -544,7 +652,7 @@
         for (Option o : recognizedOptions) {
             String name = o.aliases[0].substring(1); // there must always be at least one name
             name = name.charAt(0) == '-' ? name.substring(1) : name;
-            if (o.isHidden() || name.equals("h")) {
+            if (o.isHidden() || name.equals("h") || name.startsWith("filter:")) {
                 continue;
             }
             log.println(getMessage("main.opt." + name));
@@ -582,14 +690,18 @@
         boolean fullVersion;
         boolean showProfile;
         boolean showSummary;
-        boolean wildcard;
         boolean apiOnly;
         boolean showLabel;
         boolean findJDKInternals;
+        // default is to show package-level dependencies
+        // and filter references from same package
+        Analyzer.Type verbose = PACKAGE;
+        boolean filterSamePackage = true;
+        boolean filterSameArchive = false;
+        String filterRegex;
         String dotOutputDir;
         String classpath = "";
         int depth = 1;
-        Analyzer.Type verbose = Analyzer.Type.PACKAGE;
         Set<String> packageNames = new HashSet<>();
         String regex;             // apply to the dependences
         Pattern includePattern;   // apply to classes
@@ -613,19 +725,6 @@
         }
     }
 
-    private List<Archive> getArchives(List<String> filenames) throws IOException {
-        List<Archive> result = new ArrayList<>();
-        for (String s : filenames) {
-            Path p = Paths.get(s);
-            if (Files.exists(p)) {
-                result.add(new Archive(p, ClassFileReader.newInstance(p)));
-            } else {
-                warning("warn.file.not.exist", s);
-            }
-        }
-        return result;
-    }
-
     private List<Archive> getClassPathArchives(String paths) throws IOException {
         List<Archive> result = new ArrayList<>();
         if (paths.isEmpty()) {
@@ -648,7 +747,7 @@
                 }
                 for (Path f : files) {
                     if (Files.exists(f)) {
-                        result.add(new Archive(f, ClassFileReader.newInstance(f)));
+                        result.add(Archive.getInstance(f));
                     }
                 }
             }
@@ -656,81 +755,50 @@
         return result;
     }
 
-    /**
-     * If the given archive is JDK archive and non-null Profile,
-     * this method returns the profile name only if -profile option is specified;
-     * a null profile indicates it accesses a private JDK API and this method
-     * will return "JDK internal API".
-     *
-     * For non-JDK archives, this method returns the file name of the archive.
-     */
-    private String getProfileArchiveInfo(Archive source, Profile profile) {
-        if (options.showProfile && profile != null)
-            return profile.toString();
-
-        if (source instanceof JDKArchive) {
-            return profile == null ? "JDK internal API (" + source.getFileName() + ")" : "";
-        }
-        return source.getFileName();
-    }
-
-    /**
-     * Returns the profile name or "JDK internal API" for JDK archive;
-     * otherwise empty string.
-     */
-    private String profileName(Archive archive, Profile profile) {
-        if (archive instanceof JDKArchive) {
-            return Objects.toString(profile, "JDK internal API");
-        } else {
-            return "";
-        }
-    }
-
     class RawOutputFormatter implements Analyzer.Visitor {
         private final PrintWriter writer;
+        private String pkg = "";
         RawOutputFormatter(PrintWriter writer) {
             this.writer = writer;
         }
-
-        private String pkg = "";
         @Override
-        public void visitDependence(String origin, Archive source,
-                                    String target, Archive archive, Profile profile) {
-            if (options.findJDKInternals &&
-                    !(archive instanceof JDKArchive && profile == null)) {
-                // filter dependences other than JDK internal APIs
-                return;
-            }
-            if (options.verbose == Analyzer.Type.VERBOSE) {
-                writer.format("   %-50s -> %-50s %s%n",
-                              origin, target, getProfileArchiveInfo(archive, profile));
+        public void visitDependence(String origin, Archive originArchive,
+                                    String target, Archive targetArchive) {
+            String tag = toTag(target, targetArchive);
+            if (options.verbose == VERBOSE) {
+                writer.format("   %-50s -> %-50s %s%n", origin, target, tag);
             } else {
                 if (!origin.equals(pkg)) {
                     pkg = origin;
-                    writer.format("   %s (%s)%n", origin, source.getFileName());
+                    writer.format("   %s (%s)%n", origin, originArchive.getName());
                 }
-                writer.format("      -> %-50s %s%n",
-                              target, getProfileArchiveInfo(archive, profile));
-            }
-        }
-
-        @Override
-        public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
-            writer.format("%s -> %s", origin.getPathName(), target.getPathName());
-            if (options.showProfile && profile != null) {
-                writer.format(" (%s)%n", profile);
-            } else {
-                writer.format("%n");
+                writer.format("      -> %-50s %s%n", target, tag);
             }
         }
     }
 
-    class DotFileFormatter extends DotGraph<String> implements AutoCloseable {
+    class RawSummaryFormatter implements Analyzer.Visitor {
+        private final PrintWriter writer;
+        RawSummaryFormatter(PrintWriter writer) {
+            this.writer = writer;
+        }
+        @Override
+        public void visitDependence(String origin, Archive originArchive,
+                                    String target, Archive targetArchive) {
+            writer.format("%s -> %s", originArchive.getName(), targetArchive.getPathName());
+            if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) {
+                writer.format(" (%s)", target);
+            }
+            writer.format("%n");
+        }
+    }
+
+    class DotFileFormatter implements Analyzer.Visitor, AutoCloseable {
         private final PrintWriter writer;
         private final String name;
         DotFileFormatter(PrintWriter writer, Archive archive) {
             this.writer = writer;
-            this.name = archive.getFileName();
+            this.name = archive.getName();
             writer.format("digraph \"%s\" {%n", name);
             writer.format("    // Path: %s%n", archive.getPathName());
         }
@@ -741,173 +809,123 @@
         }
 
         @Override
-        public void visitDependence(String origin, Archive source,
-                                    String target, Archive archive, Profile profile) {
-            if (options.findJDKInternals &&
-                    !(archive instanceof JDKArchive && profile == null)) {
-                // filter dependences other than JDK internal APIs
-                return;
-            }
-            // if -P option is specified, package name -> profile will
-            // be shown and filter out multiple same edges.
-            String name = getProfileArchiveInfo(archive, profile);
-            writeEdge(writer, new Edge(origin, target, getProfileArchiveInfo(archive, profile)));
-        }
-        @Override
-        public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
-            throw new UnsupportedOperationException();
+        public void visitDependence(String origin, Archive originArchive,
+                                    String target, Archive targetArchive) {
+            String tag = toTag(target, targetArchive);
+            writer.format("   %-50s -> \"%s\";%n",
+                          String.format("\"%s\"", origin),
+                          tag.isEmpty() ? target
+                                        : String.format("%s (%s)", target, tag));
         }
     }
 
-    class DotSummaryForArchive extends DotGraph<Archive> {
+    class SummaryDotFile implements Analyzer.Visitor, AutoCloseable {
+        private final PrintWriter writer;
+        private final Analyzer.Type type;
+        private final Map<Archive, Map<Archive,StringBuilder>> edges = new HashMap<>();
+        SummaryDotFile(PrintWriter writer, Analyzer.Type type) {
+            this.writer = writer;
+            this.type = type;
+            writer.format("digraph \"summary\" {%n");
+        }
+
         @Override
-        public void visitDependence(String origin, Archive source,
-                                    String target, Archive archive, Profile profile) {
-            Edge e = findEdge(source, archive);
-            assert e != null;
-            // add the dependency to the label if enabled and not compact1
-            if (profile == Profile.COMPACT1) {
-                return;
+        public void close() {
+            writer.println("}");
+        }
+
+        @Override
+        public void visitDependence(String origin, Archive originArchive,
+                                    String target, Archive targetArchive) {
+            String targetName = type == PACKAGE ? target : targetArchive.getName();
+            if (type == PACKAGE) {
+                String tag = toTag(target, targetArchive, type);
+                if (!tag.isEmpty())
+                    targetName += " (" + tag + ")";
+            } else if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) {
+                targetName += " (" + target + ")";
             }
-            e.addLabel(origin, target, profileName(archive, profile));
+            String label = getLabel(originArchive, targetArchive);
+            writer.format("  %-50s -> \"%s\"%s;%n",
+                          String.format("\"%s\"", origin), targetName, label);
         }
-        @Override
-        public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
-            // add an edge with the archive's name with no tag
-            // so that there is only one node for each JDK archive
-            // while there may be edges to different profiles
-            Edge e = addEdge(origin, target, "");
-            if (target instanceof JDKArchive) {
-                // add a label to print the profile
-                if (profile == null) {
-                    e.addLabel("JDK internal API");
-                } else if (options.showProfile && !options.showLabel) {
-                    e.addLabel(profile.toString());
+
+        String getLabel(Archive origin, Archive target) {
+            if (edges.isEmpty())
+                return "";
+
+            StringBuilder label = edges.get(origin).get(target);
+            return label == null ? "" : String.format(" [label=\"%s\",fontsize=9]", label.toString());
+        }
+
+        Analyzer.Visitor labelBuilder() {
+            // show the package-level dependencies as labels in the dot graph
+            return new Analyzer.Visitor() {
+                @Override
+                public void visitDependence(String origin, Archive originArchive, String target, Archive targetArchive) {
+                    edges.putIfAbsent(originArchive, new HashMap<>());
+                    edges.get(originArchive).putIfAbsent(targetArchive, new StringBuilder());
+                    StringBuilder sb = edges.get(originArchive).get(targetArchive);
+                    String tag = toTag(target, targetArchive, PACKAGE);
+                    addLabel(sb, origin, target, tag);
                 }
-            }
+
+                void addLabel(StringBuilder label, String origin, String target, String tag) {
+                    label.append(origin).append(" -> ").append(target);
+                    if (!tag.isEmpty()) {
+                        label.append(" (" + tag + ")");
+                    }
+                    label.append("\\n");
+                }
+            };
         }
     }
 
-    // DotSummaryForPackage generates the summary.dot file for verbose mode
-    // (-v or -verbose option) that includes all class dependencies.
-    // The summary.dot file shows package-level dependencies.
-    class DotSummaryForPackage extends DotGraph<String> {
-        private String packageOf(String cn) {
-            int i = cn.lastIndexOf('.');
-            return i > 0 ? cn.substring(0, i) : "<unnamed>";
+    /**
+     * Test if the given archive is part of the JDK
+     */
+    private boolean isJDKArchive(Archive archive) {
+        return JDKArchive.class.isInstance(archive);
+    }
+
+    /**
+     * If the given archive is JDK archive, this method returns the profile name
+     * only if -profile option is specified; it accesses a private JDK API and
+     * the returned value will have "JDK internal API" prefix
+     *
+     * For non-JDK archives, this method returns the file name of the archive.
+     */
+    private String toTag(String name, Archive source, Analyzer.Type type) {
+        if (!isJDKArchive(source)) {
+            return source.getName();
         }
-        @Override
-        public void visitDependence(String origin, Archive source,
-                                    String target, Archive archive, Profile profile) {
-            // add a package dependency edge
-            String from = packageOf(origin);
-            String to = packageOf(target);
-            Edge e = addEdge(from, to, getProfileArchiveInfo(archive, profile));
 
-            // add the dependency to the label if enabled and not compact1
-            if (!options.showLabel || profile == Profile.COMPACT1) {
-                return;
-            }
-
-            // trim the package name of origin to shorten the label
-            int i = origin.lastIndexOf('.');
-            String n1 = i < 0 ? origin : origin.substring(i+1);
-            e.addLabel(n1, target, profileName(archive, profile));
+        JDKArchive jdk = (JDKArchive)source;
+        boolean isExported = false;
+        if (type == CLASS || type == VERBOSE) {
+            isExported = jdk.isExported(name);
+        } else {
+            isExported = jdk.isExportedPackage(name);
         }
-        @Override
-        public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
-            // nop
+        Profile p = getProfile(name, type);
+        if (isExported) {
+            // exported API
+            return options.showProfile && p != null ? p.profileName() : "";
+        } else {
+            return "JDK internal API (" + source.getName() + ")";
         }
     }
-    abstract class DotGraph<T> implements Analyzer.Visitor  {
-        private final Set<Edge> edges = new LinkedHashSet<>();
-        private Edge curEdge;
-        public void writeTo(PrintWriter writer) {
-            writer.format("digraph \"summary\" {%n");
-            for (Edge e: edges) {
-                writeEdge(writer, e);
-            }
-            writer.println("}");
+
+    private String toTag(String name, Archive source) {
+        return toTag(name, source, options.verbose);
+    }
+
+    private Profile getProfile(String name, Analyzer.Type type) {
+        String pn = name;
+        if (type == CLASS || type == VERBOSE) {
+            int i = name.lastIndexOf('.');
+            pn = i > 0 ? name.substring(0, i) : "";
         }
-
-        void writeEdge(PrintWriter writer, Edge e) {
-            writer.format("   %-50s -> \"%s\"%s;%n",
-                          String.format("\"%s\"", e.from.toString()),
-                          e.tag.isEmpty() ? e.to
-                                          : String.format("%s (%s)", e.to, e.tag),
-                          getLabel(e));
-        }
-
-        Edge addEdge(T origin, T target, String tag) {
-            Edge e = new Edge(origin, target, tag);
-            if (e.equals(curEdge)) {
-                return curEdge;
-            }
-
-            if (edges.contains(e)) {
-                for (Edge e1 : edges) {
-                   if (e.equals(e1)) {
-                       curEdge = e1;
-                   }
-                }
-            } else {
-                edges.add(e);
-                curEdge = e;
-            }
-            return curEdge;
-        }
-
-        Edge findEdge(T origin, T target) {
-            for (Edge e : edges) {
-                if (e.from.equals(origin) && e.to.equals(target)) {
-                    return e;
-                }
-            }
-            return null;
-        }
-
-        String getLabel(Edge e) {
-            String label = e.label.toString();
-            return label.isEmpty() ? "" : String.format("[label=\"%s\",fontsize=9]", label);
-        }
-
-        class Edge {
-            final T from;
-            final T to;
-            final String tag;  // optional tag
-            final StringBuilder label = new StringBuilder();
-            Edge(T from, T to, String tag) {
-                this.from = from;
-                this.to = to;
-                this.tag = tag;
-            }
-            void addLabel(String s) {
-                label.append(s).append("\\n");
-            }
-            void addLabel(String origin, String target, String profile) {
-                label.append(origin).append(" -> ").append(target);
-                if (!profile.isEmpty()) {
-                    label.append(" (" + profile + ")");
-                }
-                label.append("\\n");
-            }
-            @Override @SuppressWarnings("unchecked")
-            public boolean equals(Object o) {
-                if (o instanceof DotGraph<?>.Edge) {
-                    DotGraph<?>.Edge e = (DotGraph<?>.Edge)o;
-                    return this.from.equals(e.from) &&
-                           this.to.equals(e.to) &&
-                           this.tag.equals(e.tag);
-                }
-                return false;
-            }
-            @Override
-            public int hashCode() {
-                int hash = 7;
-                hash = 67 * hash + Objects.hashCode(this.from) +
-                       Objects.hashCode(this.to) + Objects.hashCode(this.tag);
-                return hash;
-            }
-        }
+        return Profile.getProfile(pn);
     }
 }
--- a/src/share/classes/com/sun/tools/jdeps/Main.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/Main.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -63,4 +63,3 @@
         return t.run(args);
     }
 }
-
--- a/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -24,6 +24,12 @@
  */
 package com.sun.tools.jdeps;
 
+import com.sun.tools.classfile.Annotation;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.RuntimeAnnotations_attribute;
+import com.sun.tools.classfile.Dependencies.ClassFileError;
 import java.io.IOException;
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
@@ -33,11 +39,15 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.*;
 
+import static com.sun.tools.classfile.Attribute.*;
+
 /**
  * ClassPath for Java SE and JDK
  */
 class PlatformClassPath {
-    private final static List<Archive> javaHomeArchives = init();
+    private static final List<String> NON_PLATFORM_JARFILES =
+        Arrays.asList("alt-rt.jar", "jfxrt.jar", "ant-javafx.jar", "javafx-mx.jar");
+    private static final List<Archive> javaHomeArchives = init();
 
     static List<Archive> getArchives() {
         return javaHomeArchives;
@@ -50,12 +60,19 @@
             if (home.endsWith("jre")) {
                 // jar files in <javahome>/jre/lib
                 result.addAll(addJarFiles(home.resolve("lib")));
+                if (home.getParent() != null) {
+                    // add tools.jar and other JDK jar files
+                    Path lib = home.getParent().resolve("lib");
+                    if (Files.exists(lib)) {
+                        result.addAll(addJarFiles(lib));
+                    }
+                }
             } else if (Files.exists(home.resolve("lib"))) {
                 // either a JRE or a jdk build image
                 Path classes = home.resolve("classes");
                 if (Files.isDirectory(classes)) {
                     // jdk build outputdir
-                    result.add(new JDKArchive(classes, ClassFileReader.newInstance(classes)));
+                    result.add(new JDKArchive(classes));
                 }
                 // add other JAR files
                 result.addAll(addJarFiles(home.resolve("lib")));
@@ -91,9 +108,9 @@
                 if (fn.endsWith(".jar")) {
                     // JDK may cobundle with JavaFX that doesn't belong to any profile
                     // Treat jfxrt.jar as regular Archive
-                    result.add(fn.equals("jfxrt.jar")
-                        ? new Archive(p, ClassFileReader.newInstance(p))
-                        : new JDKArchive(p, ClassFileReader.newInstance(p)));
+                    result.add(NON_PLATFORM_JARFILES.contains(fn)
+                                   ? Archive.getInstance(p)
+                                   : new JDKArchive(p));
                 }
                 return FileVisitResult.CONTINUE;
             }
@@ -106,8 +123,91 @@
      * or implementation classes (i.e. JDK internal API)
      */
     static class JDKArchive extends Archive {
-        JDKArchive(Path p, ClassFileReader reader) {
-            super(p, reader);
+        private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar");
+        public static boolean isProfileArchive(Archive archive) {
+            if (archive instanceof JDKArchive) {
+                return PROFILE_JARS.contains(archive.getName());
+            }
+            return false;
+        }
+
+        private final Map<String,Boolean> exportedPackages = new HashMap<>();
+        private final Map<String,Boolean> exportedTypes = new HashMap<>();
+        JDKArchive(Path p) throws IOException {
+            super(p, ClassFileReader.newInstance(p));
+        }
+
+        /**
+         * Tests if a given fully-qualified name is an exported type.
+         */
+        public boolean isExported(String cn) {
+            int i = cn.lastIndexOf('.');
+            String pn = i > 0 ? cn.substring(0, i) : "";
+
+            boolean isJdkExported = isExportedPackage(pn);
+            if (exportedTypes.containsKey(cn)) {
+                return exportedTypes.get(cn);
+            }
+            return isJdkExported;
+        }
+
+        /**
+         * Tests if a given package name is exported.
+         */
+        public boolean isExportedPackage(String pn) {
+            if (Profile.getProfile(pn) != null) {
+                return true;
+            }
+            return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false;
+        }
+
+        private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;";
+        private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException {
+            RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
+                    cf.attributes.get(RuntimeVisibleAnnotations);
+            if (attr != null) {
+                for (int i = 0; i < attr.annotations.length; i++) {
+                    Annotation ann = attr.annotations[i];
+                    String annType = cf.constant_pool.getUTF8Value(ann.type_index);
+                    if (JDK_EXPORTED_ANNOTATION.equals(annType)) {
+                        boolean isJdkExported = true;
+                        for (int j = 0; j < ann.num_element_value_pairs; j++) {
+                            Annotation.element_value_pair pair = ann.element_value_pairs[j];
+                            Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value;
+                            ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info)
+                                    cf.constant_pool.get(ev.const_value_index);
+                            isJdkExported = info.value != 0;
+                        }
+                        return Boolean.valueOf(isJdkExported);
+                    }
+                }
+            }
+            return null;
+        }
+
+        void processJdkExported(ClassFile cf) throws IOException {
+            try {
+                String cn = cf.getName();
+                String pn = cn.substring(0, cn.lastIndexOf('/')).replace('/', '.');
+
+                Boolean b = isJdkExported(cf);
+                if (b != null) {
+                    exportedTypes.put(cn.replace('/', '.'), b);
+                }
+                if (!exportedPackages.containsKey(pn)) {
+                    // check if package-info.class has @jdk.Exported
+                    Boolean isJdkExported = null;
+                    ClassFile pcf = reader().getClassFile(cn.substring(0, cn.lastIndexOf('/')+1) + "package-info");
+                    if (pcf != null) {
+                        isJdkExported = isJdkExported(pcf);
+                    }
+                    if (isJdkExported != null) {
+                        exportedPackages.put(pn, isJdkExported);
+                    }
+                }
+            } catch (ConstantPoolException e) {
+                throw new ClassFileError(e);
+            }
         }
     }
 }
--- a/src/share/classes/com/sun/tools/jdeps/Profile.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/Profile.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -43,7 +43,6 @@
  * Build the profile information from ct.sym if exists.
  */
 enum Profile {
-
     COMPACT1("compact1", 1),
     COMPACT2("compact2", 2),
     COMPACT3("compact3", 3),
@@ -61,8 +60,7 @@
         this.proprietaryPkgs = new HashSet<>();
     }
 
-    @Override
-    public String toString() {
+    public String profileName() {
         return name;
     }
 
@@ -77,7 +75,7 @@
     public static Profile getProfile(String pn) {
         Profile profile = PackageToProfile.map.get(pn);
         return (profile != null && profile.packages.contains(pn))
-                ? profile : null;
+                    ? profile : null;
     }
 
     static class PackageToProfile {
--- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Thu Jul 10 12:13:35 2014 -0700
+++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Thu Jul 10 12:39:26 2014 -0700
@@ -1,6 +1,6 @@
 main.usage.summary=\
 Usage: {0} <options> <classes...>\n\
-use -h, -? or --help for a list of possible options
+use -h, -? or -help for a list of possible options
 
 main.usage=\
 Usage: {0} <options> <classes...>\n\
@@ -18,20 +18,29 @@
 
 main.opt.v=\
 \  -v           -verbose              Print all class level dependencies\n\
+\                                     Equivalent to -verbose:class -filter:none.\n\
 \  -verbose:package                   Print package-level dependencies excluding\n\
-\                                     dependencies within the same archive\n\
+\                                     dependencies within the same package by default\n\
 \  -verbose:class                     Print class-level dependencies excluding\n\
-\                                     dependencies within the same archive
+\                                     dependencies within the same package by default
+
+main.opt.f=\
+\  -f <regex>   -filter <regex>       Filter dependences matching the given pattern\n\
+\                                     If given multiple times, the last one will be used.\n\
+\  -filter:package                    Filter dependences within the same package (default)\n\
+\  -filter:archive                    Filter dependences within the same archive\n\
+\  -filter:none                       No -filter:package and -filter:archive filtering\n\
+\                                     Filtering specified via the -filter option still applies.
 
 main.opt.s=\
 \  -s           -summary              Print dependency summary only
 
 main.opt.p=\
-\  -p <pkgname> -package <pkgname>    Finds dependences in the given package\n\
+\  -p <pkgname> -package <pkgname>    Finds dependences matching the given package name\n\
 \                                     (may be given multiple times)
 
 main.opt.e=\
-\  -e <regex>   -regex <regex>        Finds dependences in packages matching pattern\n\
+\  -e <regex>   -regex <regex>        Finds dependences matching the given pattern\n\
 \                                     (-p and -e are exclusive)
 
 main.opt.include=\
@@ -47,7 +56,10 @@
 \  -cp <path>   -classpath <path>     Specify where to find class files
 
 main.opt.R=\
-\  -R           -recursive            Recursively traverse all dependencies
+\  -R           -recursive            Recursively traverse all dependencies.\n\
+\                                     The -R option implies -filter:none.  If -p, -e, -f\n\
+\                                     option is specified, only the matching dependences\n\
+\                                     are analyzed.
 
 main.opt.apionly=\
 \  -apionly                           Restrict analysis to APIs i.e. dependences\n\
@@ -74,12 +86,11 @@
 
 err.unknown.option=unknown option: {0}
 err.missing.arg=no value given for {0}
-err.internal.error=internal error: {0} {1} {2}
 err.invalid.arg.for.option=invalid argument for option: {0}
 err.option.after.class=option must be specified before classes: {0}
 err.option.unsupported={0} not supported: {1}
 err.profiles.msg=No profile information
-err.dot.output.path=invalid path: {0}
+err.invalid.path=invalid path: {0}
 warn.invalid.arg=Invalid classname or pathname not exist: {0}
 warn.split.package=package {0} defined in {1} {2}
 
--- a/test/tools/javac/6402516/CheckLocalElements.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/6402516/CheckLocalElements.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -23,19 +23,24 @@
 
 /*
  * @test
- * @bug 6402516
+ * @bug 6402516 8031569
  * @summary need Trees.getScope(TreePath)
  * @build Checker CheckLocalElements
  * @run main CheckLocalElements
  */
 
+import java.io.IOException;
 import java.util.*;
-import com.sun.source.tree.*;
+import java.util.regex.*;
+
 import javax.lang.model.element.*;
 import javax.lang.model.util.*;
 
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+
 /*
- * Check the local elements of a scope against the contents of string literals.
+ * Check the local elements of a scope against the contents of string literals and top-level comment.
  */
 public class CheckLocalElements extends Checker {
     public static void main(String... args) throws Exception {
@@ -90,6 +95,16 @@
         return true;
     }
 
+    @Override
+    void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {
+        Matcher m = TOPLEVEL_SCOPE_DEF.matcher(topLevel.getSourceFile().getCharContent(false));
+        if (!m.find())
+            throw new AssertionError("Should have top-level scope def!");
+        check(trees.getScope(new TreePath(topLevel)), m.group(1));
+    }
+    //where:
+        Pattern TOPLEVEL_SCOPE_DEF = Pattern.compile("TOPLEVEL_SCOPE:(.*)");
+
     private String getEnclosingName(Element e) {
         Element encl = e.getEnclosingElement();
         return encl == null ? "" : encl.accept(qualNameVisitor, null);
--- a/test/tools/javac/6402516/Checker.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/6402516/Checker.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -67,6 +67,7 @@
         for (CompilationUnitTree unit: units) {
             TreePath p = new TreePath(unit);
             s.scan(p, getTrees());
+            additionalChecks(getTrees(), unit);
         }
         task = null;
 
@@ -111,6 +112,9 @@
         throw new IllegalStateException();
     }
 
+    void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {
+    }
+
     void error(Scope s, String ref, String msg) {
         System.err.println("Error: " + msg);
         System.err.println("Scope: " + (s == null ? null : asList(s.getLocalElements())));
--- a/test/tools/javac/6402516/TestLocalElements.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/6402516/TestLocalElements.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, 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
@@ -23,7 +23,7 @@
 
 import java.util.List;
 import java.io.*;
-
+//TOPLEVEL_SCOPE:List, Test2, Test; java.io.*, java.lang.*
 class Test {
     void m1(int m1_arg) {
         String x = "x, m1_arg, super, this; List, Test2, Test; java.io.*, java.lang.*";
--- a/test/tools/javac/6889255/T6889255.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/6889255/T6889255.java	Thu Jul 10 12:39:26 2014 -0700
@@ -32,7 +32,7 @@
 import javax.tools.StandardLocation;
 import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Type;
@@ -43,6 +43,8 @@
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Names;
 
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+
 public class T6889255 {
     boolean testInterfaces = true;
     boolean testSyntheticMethods = true;
@@ -380,11 +382,11 @@
             if ((sym.flags() & Flags.INTERFACE) != 0 && !testInterfaces)
                 continue;
 
-            for (Scope.Entry e = sym.members_field.elems; e != null; e = e.sibling) {
-                System.err.println("Checking member " + e.sym);
-                switch (e.sym.kind) {
+            for (Symbol s : sym.members_field.getSymbols(NON_RECURSIVE)) {
+                System.err.println("Checking member " + s);
+                switch (s.kind) {
                     case Kinds.TYP: {
-                        String name = e.sym.flatName().toString();
+                        String name = s.flatName().toString();
                         if (!classes.contains(name)) {
                             classes.add(name);
                             work.add(name);
@@ -392,7 +394,7 @@
                         break;
                     }
                     case Kinds.MTH:
-                        verify((MethodSymbol) e.sym, expectNames);
+                        verify((MethodSymbol) s, expectNames);
                         break;
                 }
 
--- a/test/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java	Thu Jul 10 12:39:26 2014 -0700
@@ -45,7 +45,7 @@
      */
     protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception {
 
-        Map<String, ? extends JavaFileObject> classes = compile(sourceCode);
+        Map<String, ? extends JavaFileObject> classes = compile(sourceCode).getClasses();
         String fileName = ToolBox.getJavaFileNameFromSource(sourceCode);
         for (String className : classesToTest) {
             assertAttributePresent(ClassFile.read(classes.get(className).openInputStream()), fileName);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, 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 8042261
+ * @summary Checking that deprecated attribute does not apply to classes of deprecated package.
+ * @library /tools/javac/lib ../lib
+ * @build DeprecatedPackageTest TestBase TestResult InMemoryFileManager ToolBox
+ * @run main DeprecatedPackageTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Deprecated_attribute;
+
+public class DeprecatedPackageTest extends TestResult {
+
+    private static final String[] sourceTest = new String[]{
+        "package deprecated;\n"
+        + "public class notDeprecated{}",
+        "package deprecated;\n"
+        + "public interface notDeprecated{}",
+        "package deprecated;\n"
+        + "public @interface notDeprecated{}",
+        "package deprecated;\n"
+        + "public enum notDeprecated{}"
+    };
+
+    private static final String CLASS_NAME = "deprecated.notDeprecated";
+
+    private static final String PACKAGE_INFO =
+            "@Deprecated\n" +
+            "package deprecated;";
+
+    public static void main(String[] args) throws TestFailedException {
+        new DeprecatedPackageTest().test();
+    }
+
+    private void test() throws TestFailedException {
+        try {
+            for (String src : sourceTest) {
+                test(PACKAGE_INFO, src);
+                test(PACKAGE_INFO.replaceAll("@Deprecated", "/** @deprecated */"), src);
+            }
+        } catch (Exception e) {
+            addFailure(e);
+        } finally {
+            checkStatus();
+        }
+    }
+
+    private void test(String package_info, String src) {
+        addTestCase(src);
+        printf("Testing test case: \n%s\n", src);
+        try {
+            ClassFile cf = ClassFile.read(compile(
+                        new String[]{"package-info.java", package_info},
+                        new String[]{"notDeprecated.java", src})
+                    .getClasses().get(CLASS_NAME).openInputStream());
+            Deprecated_attribute attr =
+                    (Deprecated_attribute) cf.getAttribute(Attribute.Deprecated);
+            assertNull(attr, "Class can not have deprecated attribute : " + CLASS_NAME);
+        } catch (Exception e) {
+            addFailure(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2014, 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 8042261
+ * @summary Checking what attribute is generated by annotation Deprecated
+ *          or javadoc deprecated for field, method, class(inner/local), interface.
+ * @library /tools/javac/lib ../lib
+ * @build DeprecatedTest TestBase TestResult InMemoryFileManager ToolBox
+ * @run main DeprecatedTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Deprecated_attribute;
+import com.sun.tools.classfile.Field;
+import com.sun.tools.classfile.InnerClasses_attribute;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+import com.sun.tools.classfile.Method;
+
+import javax.tools.JavaFileObject;
+import java.io.IOException;
+import java.util.Map;
+
+public class DeprecatedTest extends TestResult {
+
+    private static final String[] sources = new String[]{
+            "@Deprecated public class deprecated {\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated public void deprecated() {}\n"
+            + "@Deprecated public int deprecated;\n"
+            + "public void notDeprecated() {}\n"
+            + "public int notDeprecated;\n"
+            + "public void f() {\n"
+            + "    @Deprecated class deprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }\n"
+            + "    class notDeprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }}\n"
+            + "}",
+            "@Deprecated public interface deprecated {\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated void deprecated01();\n"
+            + "void notDeprecated01();\n"
+            + "@Deprecated default void deprecated02() {}\n"
+            + "default void notDeprecated02() {}\n"
+            + "@Deprecated int deprecated = 0;\n"
+            + "int notDeprecated = 0;\n"
+            + "}",
+            "@Deprecated public enum deprecated {\n"
+            + "@Deprecated deprecated, notDeprecated;\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated public void deprecated() {}\n"
+            + "public void notDeprecated() {}\n"
+            + "public void f() {\n"
+            + "    @Deprecated class deprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }\n"
+            + "    class notDeprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }}\n"
+            + "}",
+            "@Deprecated public @interface deprecated {\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated int deprecated() default 0;\n"
+            + "int notDeprecated() default 0;\n"
+            + "@Deprecated int deprecated = 0;\n"
+            + "int notDeprecated = 0;\n"
+            + "}",
+            "public class notDeprecated {\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated public void deprecated() {}\n"
+            + "@Deprecated public int deprecated;\n"
+            + "public void notDeprecated() {}\n"
+            + "public int notDeprecated;\n"
+            + "public void f() {\n"
+            + "    @Deprecated class deprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }\n"
+            + "    class notDeprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }}\n"
+            + "}",
+            "public interface notDeprecated {\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated void deprecated01();\n"
+            + "void notDeprecated01();\n"
+            + "@Deprecated default void deprecated02() {}\n"
+            + "default void notDeprecated02() {}\n"
+            + "@Deprecated int deprecated = 0;\n"
+            + "int notDeprecated = 0;\n"
+            + "}",
+            "public enum notDeprecated {\n"
+            + "@Deprecated deprecated, notDeprecated;\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated public void deprecated() {}\n"
+            + "public void notDeprecated() {}\n"
+            + "public void f() {\n"
+            + "    @Deprecated class deprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }\n"
+            + "    class notDeprecatedLocal {\n"
+            + "        @Deprecated int deprecated;\n"
+            + "        @Deprecated void deprecated() {}\n"
+            + "        int notDeprecated;\n"
+            + "        void notDeprecated(){}\n"
+            + "    }}\n"
+            + "}",
+            "public @interface notDeprecated {\n"
+            + "@Deprecated class deprecatedInner01 {}\n"
+            + "@Deprecated interface deprecatedInner02 {}\n"
+            + "@Deprecated enum deprecatedInner03 {}\n"
+            + "@Deprecated @interface deprecatedInner04 {}\n"
+            + "class notDeprecatedInner01 {}\n"
+            + "interface notDeprecatedInner02 {}\n"
+            + "enum notDeprecatedInner03 {}\n"
+            + "@interface notDeprecatedInner04 {}\n"
+            + "@Deprecated int deprecated() default 0;\n"
+            + "int notDeprecated() default 0;\n"
+            + "@Deprecated int deprecated = 0;\n"
+            + "int notDeprecated = 0;\n"
+            + "}"};
+
+    public static void main(String[] args) throws TestFailedException {
+        new DeprecatedTest().test();
+    }
+
+    public void test() throws TestFailedException {
+        try {
+            for (String src : sources) {
+                test(src);
+                test(src.replaceAll("@Deprecated", "/** @deprecated */"));
+            }
+        } catch (Exception e) {
+            addFailure(e);
+        } finally {
+            checkStatus();
+        }
+    }
+
+    private void test(String src) {
+        addTestCase(src);
+        printf("Testing test case :\n%s\n", src);
+        try {
+            Map<String, ? extends JavaFileObject> classes = compile(src).getClasses();
+            String outerClassName = classes.containsKey("deprecated")
+                    ? "deprecated"
+                    : "notDeprecated";
+            echo("Testing outer class : " + outerClassName);
+            ClassFile cf = ClassFile.read(classes.get(outerClassName).openInputStream());
+            Deprecated_attribute attr = (Deprecated_attribute)
+                    cf.getAttribute(Attribute.Deprecated);
+            testAttribute(outerClassName, attr, cf);
+            testInnerClasses(cf, classes);
+            testMethods(cf);
+            testFields(cf);
+        } catch (Exception e) {
+            addFailure(e);
+        }
+    }
+
+    private void testInnerClasses(ClassFile cf, Map<String, ? extends JavaFileObject> classes)
+            throws ConstantPoolException, IOException {
+        InnerClasses_attribute innerAttr = (InnerClasses_attribute)
+                cf.getAttribute(Attribute.InnerClasses);
+        for (Info innerClass : innerAttr.classes) {
+            String innerClassName = cf.constant_pool.
+                    getClassInfo(innerClass.inner_class_info_index).getName();
+            echo("Testing inner class : " + innerClassName);
+            ClassFile innerCf = ClassFile.read(classes.get(innerClassName).openInputStream());
+            Deprecated_attribute attr = (Deprecated_attribute)
+                    innerCf.getAttribute(Attribute.Deprecated);
+            String innerClassSimpleName = innerClass.getInnerName(cf.constant_pool);
+            testAttribute(innerClassSimpleName, attr, innerCf);
+            if (innerClassName.contains("Local")) {
+                testMethods(innerCf);
+                testFields(innerCf);
+            }
+        }
+    }
+
+    private void testMethods(ClassFile cf)
+            throws ConstantPoolException {
+        for (Method m : cf.methods) {
+            String methodName = cf.constant_pool.getUTF8Value(m.name_index);
+            echo("Testing method : " + methodName);
+            Deprecated_attribute attr = (Deprecated_attribute)
+                    m.attributes.get(Attribute.Deprecated);
+            testAttribute(methodName, attr, cf);
+        }
+    }
+
+    private void testFields(ClassFile cf) throws ConstantPoolException {
+        for (Field f : cf.fields) {
+            String fieldName = cf.constant_pool.getUTF8Value(f.name_index);
+            echo("Testing field : " + fieldName);
+            Deprecated_attribute attr = (Deprecated_attribute)
+                    f.attributes.get(Attribute.Deprecated);
+            testAttribute(fieldName, attr, cf);
+        }
+    }
+
+    private void testAttribute(String name, Deprecated_attribute attr, ClassFile cf)
+            throws ConstantPoolException {
+        if (name.contains("deprecated")) {
+            testDeprecatedAttribute(name, attr, cf);
+        } else {
+            assertNull(attr, name + " should not have deprecated attribute");
+        }
+    }
+
+    private void testDeprecatedAttribute(String name, Deprecated_attribute attr, ClassFile cf)
+            throws ConstantPoolException {
+        assertNotNull(attr, name + " must have deprecated attribute");
+        assertEquals(0, attr.attribute_length,
+                "attribute_length should equal to 0");
+        assertEquals("Deprecated",
+                cf.constant_pool.getUTF8Value(attr.attribute_name_index),
+                name + " attribute_name_index");
+    }
+}
--- a/test/tools/javac/classfiles/attributes/lib/TestBase.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/classfiles/attributes/lib/TestBase.java	Thu Jul 10 12:39:26 2014 -0700
@@ -23,47 +23,85 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.io.PrintStream;
+import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Stream;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.ToolProvider;
+import javax.tools.*;
 
 import static java.lang.String.format;
+import static java.lang.System.lineSeparator;
+import static java.util.Arrays.asList;
 import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toList;
 
 public class TestBase {
 
-    public Map<String, ? extends JavaFileObject> compile(String... sources) throws IOException,
+    public static final String LINE_SEPARATOR = lineSeparator();
+
+    private <S> InMemoryFileManager compile(
+            List<String> options,
+            Function<S, ? extends JavaFileObject> src2JavaFileObject,
+            List<S> sources)
+            throws IOException, CompilationException {
+
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        List<? extends JavaFileObject> src = sources.stream()
+                .map(src2JavaFileObject)
+                .collect(toList());
+
+        DiagnosticCollector<? super JavaFileObject> dc = new DiagnosticCollector<>();
+        try (InMemoryFileManager fileManager
+                     = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) {
+            JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, dc, options, null, src);
+            boolean success = task.call();
+            if (!success) {
+                String errorMessage = dc.getDiagnostics().stream()
+                        .map(Object::toString)
+                        .collect(joining("\n"));
+                throw new CompilationException("Compilation Error\n\n" + errorMessage);
+            }
+            return fileManager;
+        }
+    }
+
+    public InMemoryFileManager compile(String... sources)
+            throws IOException, CompilationException {
+        return compile(emptyList(), sources);
+    }
+
+    /**
+     * @param options - compiler options
+     * @param sources
+     * @return map where key is className, value is corresponding ClassFile.
+     * @throws IOException
+     */
+    public InMemoryFileManager compile(List<String> options, String...sources)
+            throws IOException, CompilationException {
+        return compile(options, ToolBox.JavaSource::new, asList(sources));
+    }
+
+    public InMemoryFileManager compile(String[]... sources) throws IOException,
             CompilationException {
         return compile(emptyList(), sources);
     }
 
     /**
      * @param options -  compiler options
-     * @param sources
+     * @param sources - sources[i][0] - name of file, sources[i][1] - sources
      * @return map where key is className, value is corresponding ClassFile.
      * @throws IOException
+     * @throws CompilationException
      */
-    public Map<String, ? extends JavaFileObject> compile(List<String> options, String... sources) throws IOException,
-            CompilationException {
-
-        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
-        List<? extends JavaFileObject> src = Stream.of(sources).map(ToolBox.JavaSource::new).collect(toList());
-
-        try (InMemoryFileManager fileManager = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) {
-            boolean success = compiler.getTask(null, fileManager, null, options, null, src).call();
-            if (!success) throw new CompilationException("Compilation Error");
-            return fileManager.getClasses();
-        }
+    public InMemoryFileManager compile(List<String> options, String[]...sources)
+            throws IOException, CompilationException {
+        return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), asList(sources));
     }
 
     public void assertEquals(Object actual, Object expected, String message) {
         if (!Objects.equals(actual, expected))
-            throw new AssertionFailedException(format("%s%nGot: %s, Expected: ", message, actual, expected));
+            throw new AssertionFailedException(format("%s%nGot: %s, Expected: %s", message, actual, expected));
     }
 
     public void assertNull(Object actual, String message) {
@@ -80,18 +118,43 @@
         assertEquals(actual, true, message);
     }
 
+    public void assertFalse(boolean actual, String message) {
+        assertEquals(actual, false, message);
+    }
+
+    public File getSourceDir() {
+        return new File(System.getProperty("test.src", "."));
+    }
+
+    public File getClassDir() {
+        return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath()));
+    }
+
     public File getSourceFile(String fileName) {
-        return new File(System.getProperty("test.src", "."), fileName);
+        return new File(getSourceDir(), fileName);
     }
 
     public File getClassFile(String fileName) {
-        return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath()), fileName);
+        return new File(getClassDir(), fileName);
     }
 
     public File getClassFile(Class clazz) {
         return getClassFile(clazz.getName().replace(".", "/") + ".class");
     }
 
+    public void echo(String message) {
+        System.err.println(message.replace("\n", LINE_SEPARATOR));
+    }
+
+    public void printf(String template, Object...args) {
+        System.err.printf(template, Stream.of(args)
+                .map(Objects::toString)
+                .map(m -> m.replace("\n", LINE_SEPARATOR))
+                .collect(toList())
+                .toArray());
+
+    }
+
     public static class CompilationException extends Exception {
 
         public CompilationException(String message) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/classfiles/attributes/lib/TestResult.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static java.lang.String.format;
+import static java.util.stream.Collectors.joining;
+
+public class TestResult extends TestBase {
+
+    private final List<Info> testCases;
+
+    public TestResult() {
+        testCases = new ArrayList<>();
+        testCases.add(new Info("Global test info"));
+    }
+
+    public void addTestCase(String src) {
+        testCases.add(new Info(src));
+    }
+
+    public String errorMessage() {
+        return testCases.stream().filter(Info::isFailed)
+                .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(),
+                        (tc.asserts.size() > 0 ? tc.getAssertMessage() + "\n" : "")
+                                + tc.getErrorMessage()))
+                .collect(joining("\n"));
+    }
+
+    @Override
+    public void assertEquals(Object actual, Object expected, String message) {
+        getLastTestCase().assertEquals(actual, expected, message);
+    }
+
+    @Override
+    public void assertNull(Object actual, String message) {
+        getLastTestCase().assertEquals(actual, null, message);
+    }
+
+    @Override
+    public void assertNotNull(Object actual, String message) {
+        getLastTestCase().assertNotNull(actual, message);
+    }
+
+    @Override
+    public void assertFalse(boolean actual, String message) {
+        getLastTestCase().assertEquals(actual, false, message);
+    }
+
+    @Override
+    public void assertTrue(boolean actual, String message) {
+        getLastTestCase().assertEquals(actual, true, message);
+    }
+
+    public void addFailure(Throwable th) {
+        getLastTestCase().addFailure(th);
+    }
+
+    private Info getLastTestCase() {
+        if (testCases.size() == 1) {
+            throw new IllegalStateException("Test case should be created");
+        }
+        return testCases.get(testCases.size() - 1);
+    }
+
+    public void checkStatus() throws TestFailedException {
+        if (testCases.stream().anyMatch(Info::isFailed)) {
+            echo(errorMessage());
+            throw new TestFailedException("Test failed");
+        }
+    }
+
+    private class Info {
+
+        private final String info;
+        private final List<String> asserts;
+        private final List<Throwable> errors;
+
+        private Info(String info) {
+            this.info = info;
+            asserts = new ArrayList<>();
+            errors = new ArrayList<>();
+        }
+
+        public String info() {
+            return info;
+        }
+
+        public boolean isFailed() {
+            return !asserts.isEmpty() || !errors.isEmpty();
+        }
+
+        public void addFailure(Throwable th) {
+            errors.add(th);
+            printf("[ERROR] : %s\n", getStackTrace(th));
+        }
+
+        public void addFailure(String message) {
+            asserts.add(message);
+            printf("[ASSERT] : %s\n", message);
+        }
+
+        public void assertEquals(Object actual, Object expected, String message) {
+            echo("Testing : " + message);
+            if (!Objects.equals(actual, expected)) {
+                addFailure(message + ": Got: " + actual + ", " + "Expected: " + expected);
+            }
+        }
+
+        public void assertNotNull(Object actual, String message) {
+            echo("Testing : " + message);
+            if (actual == null) {
+                addFailure(message + " : Expected not null value");
+            }
+        }
+
+        public String getAssertMessage() {
+            return asserts.stream()
+                    .map(failure -> "[ASSERT] : " + failure)
+                    .collect(joining("\n"));
+        }
+
+        public String getErrorMessage() {
+            return errors.stream()
+                    .map(throwable ->
+                            format("[ERROR] : %s", getStackTrace(throwable)))
+                    .collect(joining("\n"));
+        }
+
+        public String getStackTrace(Throwable throwable) {
+            StringWriter stringWriter = new StringWriter();
+            try (PrintWriter printWriter = new PrintWriter(stringWriter)) {
+                throwable.printStackTrace(printWriter);
+            }
+            return stringWriter.toString();
+        }
+    }
+
+    public static class TestFailedException extends Exception {
+        public TestFailedException(String message) {
+            super(message);
+        }
+    }
+}
--- a/test/tools/javac/enum/AbstractEmptyEnum.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/AbstractEmptyEnum.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5009601
  * @summary empty enum cannot be abstract
  * @author Joseph D. Darcy
  *
- * @compile/fail AbstractEmptyEnum.java
+ * @compile/fail/ref=AbstractEmptyEnum.out -XDrawDiagnostics  AbstractEmptyEnum.java
  */
 
 public enum AbstractEmptyEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/AbstractEmptyEnum.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+AbstractEmptyEnum.java:10:8: compiler.err.does.not.override.abstract: AbstractEmptyEnum, m(), AbstractEmptyEnum
+1 error
--- a/test/tools/javac/enum/Enum2.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/Enum2.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,8 @@
 /*
- * Copyright (c) 2003, 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
+ * @test /nodynamiccopyright/
  * @summary enums: an enumeration type may not be extended
  * @author gafter
- *
- * @compile/fail Enum2.java
+ * @compile/fail/ref=Enum2.out -XDrawDiagnostics  Enum2.java
  */
 
 public class Enum2 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/Enum2.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+Enum2.java:10:29: compiler.err.cant.inherit.from.final: Enum2.e1
+Enum2.java:10:12: compiler.err.enum.types.not.extensible
+2 errors
--- a/test/tools/javac/enum/FauxEnum1.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/FauxEnum1.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5009574
  * @summary verify java.lang.Enum can't be directly subclassed
  * @author Joseph D. Darcy
  *
- * @compile/fail FauxEnum1.java
+ * @compile/fail/ref=FauxEnum1.out -XDrawDiagnostics  FauxEnum1.java
  */
 
 public class FauxEnum1 extends java.lang.Enum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/FauxEnum1.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxEnum1.java:10:8: compiler.err.enum.no.subclassing
+1 error
--- a/test/tools/javac/enum/FauxEnum3.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/FauxEnum3.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5009574
  * @summary verify an enum type can't be directly subclassed
  * @author Joseph D. Darcy
  *
- * @compile/fail FauxEnum3.java
+ * @compile/fail/ref=FauxEnum3.out -XDrawDiagnostics  FauxEnum3.java
  */
 
 public class FauxEnum3 extends SpecializedEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/FauxEnum3.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxEnum3.java:10:8: compiler.err.enum.types.not.extensible
+1 error
--- a/test/tools/javac/enum/FauxSpecialEnum1.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/FauxSpecialEnum1.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5009601
  * @summary verify specialized enum classes can't be abstract
  * @author Joseph D. Darcy
  *
- * @compile/fail FauxSpecialEnum1.java
+ * @compile/fail/ref=FauxSpecialEnum1.out -XDrawDiagnostics  FauxSpecialEnum1.java
  */
 
 public enum FauxSpecialEnum1 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/FauxSpecialEnum1.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxSpecialEnum1.java:14:5: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: FauxSpecialEnum1$2, test(), compiler.misc.anonymous.class: FauxSpecialEnum1$2
+1 error
--- a/test/tools/javac/enum/FauxSpecialEnum2.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/FauxSpecialEnum2.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5009601
  * @summary verify specialized enum classes can't be abstract
  * @author Joseph D. Darcy
  *
- * @compile/fail FauxSpecialEnum2.java
+ * @compile/fail/ref=FauxSpecialEnum2.out -XDrawDiagnostics  FauxSpecialEnum2.java
  */
 
 public enum FauxSpecialEnum2 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/FauxSpecialEnum2.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxSpecialEnum2.java:12:5: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: FauxSpecialEnum2$1, test(), compiler.misc.anonymous.class: FauxSpecialEnum2$1
+1 error
--- a/test/tools/javac/enum/LocalEnum.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/LocalEnum.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,9 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5019609
  * @summary javac fails to reject local enums
  * @author gafter
- *
- * @compile/fail LocalEnum.java
+ * @compile/fail/ref=LocalEnum.out -XDrawDiagnostics  LocalEnum.java
  */
 
 public class LocalEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/LocalEnum.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+LocalEnum.java:11:9: compiler.err.local.enum
+1 error
--- a/test/tools/javac/enum/NestedEnum.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/NestedEnum.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2004, 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
+ * @test /nodynamiccopyright/
  * @bug 5071831
  * @summary javac allows enum in an inner class
  * @author gafter
  *
- * @compile/fail NestedEnum.java
+ * @compile/fail/ref=NestedEnum.out -XDrawDiagnostics  NestedEnum.java
  */
 
 class NestedEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/NestedEnum.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NestedEnum.java:12:9: compiler.err.enums.must.be.static
+1 error
--- a/test/tools/javac/enum/NoFinal.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/NoFinal.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2004, 2006, 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
+ * @test /nodynamiccopyright/
  * @bug 5097250 5087624
  * @summary Finalize methods on enums must be compile time error
  * @author Peter von der Ah\u00e9
- * @compile/fail NoFinal.java
+ * @compile/fail/ref=NoFinal.out -XDrawDiagnostics  NoFinal.java
  */
 
 enum NoFinal {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/NoFinal.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal.java:11:24: compiler.err.enum.no.finalize
+1 error
--- a/test/tools/javac/enum/NoFinal2.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/NoFinal2.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2004, 2006, 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
+ * @test /nodynamiccopyright/
  * @bug 5097250 5087624
  * @summary Finalize methods on enums must be compile time error
  * @author Peter von der Ah\u00e9
- * @compile/fail NoFinal2.java
+ * @compile/fail/ref=NoFinal2.out -XDrawDiagnostics  NoFinal2.java
  */
 
 enum NoFinal2 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/NoFinal2.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal2.java:11:20: compiler.err.enum.no.finalize
+1 error
--- a/test/tools/javac/enum/NoFinal3.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/NoFinal3.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2004, 2006, 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
+ * @test /nodynamiccopyright/
  * @bug 5097250 5087624
  * @summary Finalize methods on enums must be compile time error
  * @author Peter von der Ah\u00e9
- * @compile/fail NoFinal3.java
+ * @compile/fail/ref=NoFinal3.out -XDrawDiagnostics  NoFinal3.java
  */
 
 enum NoFinal3 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/NoFinal3.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal3.java:11:17: compiler.err.enum.no.finalize
+1 error
--- a/test/tools/javac/enum/NoFinal4.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/NoFinal4.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2004, 2006, 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
+ * @test /nodynamiccopyright/
  * @bug 5097250 5087624
  * @summary Finalize methods on enums must be compile time error
  * @author Peter von der Ah\u00e9
- * @compile/fail NoFinal4.java
+ * @compile/fail/ref=NoFinal4.out -XDrawDiagnostics  NoFinal4.java
  */
 
 enum NoFinal4 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/NoFinal4.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal4.java:11:18: compiler.err.enum.no.finalize
+1 error
--- a/test/tools/javac/enum/NoFinal5.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/NoFinal5.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2004, 2006, 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
+ * @test /nodynamiccopyright/
  * @bug 5097250 5087624
  * @summary Finalize methods on enums must be compile time error
  * @author Peter von der Ah\u00e9
- * @compile/fail NoFinal5.java
+ * @compile/fail/ref=NoFinal5.out -XDrawDiagnostics  NoFinal5.java
  */
 
 enum NoFinal5 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/NoFinal5.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal5.java:11:10: compiler.err.enum.no.finalize
+1 error
--- a/test/tools/javac/enum/T5081785.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/T5081785.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,43 +1,31 @@
 /*
- * Copyright (c) 2004, 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 /nodynamiccopyright/
+ * @bug 5081785
+ * @summary Empty Enums allowed in non-static contexts
+ * @author Peter von der Ah\u00e9
+ * @compile/fail/ref=T5081785.out -XDrawDiagnostics  T5081785.java
  */
 
-/*
- * @test
- * @bug 5081785
- *
- * @summary Empty Enums allowed in non-static contexts
- * @author Peter von der Ah\u00e9
- *
- * @compile/fail T5081785.java
- * @compile/fail T5081785a.java
- * @compile/fail T5081785b.java
- * @compile/fail T5081785c.java
- */
-
-class A {
+class A1 {
     public void check() {
         class Foo {
             enum STRENGTH{};
         };
     }
 }
+
+class A2 {
+    public A2 check() {
+        return new A2() { enum STRENGTH{}; };
+    }
+}
+
+class A3 {
+    Object o = new Object() { enum STRENGTH{}; };
+}
+
+class A4 {
+    class B {
+        enum C { X, Y, Z }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/T5081785.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,5 @@
+T5081785.java:29:9: compiler.err.enums.must.be.static
+T5081785.java:12:13: compiler.err.enums.must.be.static
+T5081785.java:19:27: compiler.err.enums.must.be.static
+T5081785.java:24:31: compiler.err.enums.must.be.static
+4 errors
--- a/test/tools/javac/enum/T5081785a.java	Thu Jul 10 12:13:35 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-class A {
-    public A check() {
-        return new A() { enum STRENGTH{}; };
-    }
-}
--- a/test/tools/javac/enum/T5081785b.java	Thu Jul 10 12:13:35 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-class A {
-    Object o = new Object() { enum STRENGTH{}; };
-}
--- a/test/tools/javac/enum/T5081785c.java	Thu Jul 10 12:13:35 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-class A {
-    class B {
-        enum C { X, Y, Z }
-    }
-}
--- a/test/tools/javac/enum/forwardRef/TestEnum1.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/forwardRef/TestEnum1.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2005, 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6209839
  * @summary Illegal forward reference to enum constants allowed by javac
  * @author  Peter von der Ah\u00e9
- * @compile/fail TestEnum1.java
+ * @compile/fail/ref=TestEnum1.out -XDrawDiagnostics  TestEnum1.java
  */
 
 enum TestEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/forwardRef/TestEnum1.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+TestEnum1.java:11:39: compiler.err.illegal.enum.static.ref
+TestEnum1.java:12:40: compiler.err.illegal.enum.static.ref
+2 errors
--- a/test/tools/javac/enum/forwardRef/TestEnum2.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/forwardRef/TestEnum2.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2005, 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6209839
  * @summary Illegal forward reference to enum constants allowed by javac
  * @author  Peter von der Ah\u00e9
- * @compile/fail TestEnum2.java
+ * @compile/fail/ref=TestEnum2.out -XDrawDiagnostics  TestEnum2.java
  */
 
 enum TestEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/forwardRef/TestEnum2.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+TestEnum2.java:13:36: compiler.err.illegal.enum.static.ref
+TestEnum2.java:14:36: compiler.err.illegal.enum.static.ref
+2 errors
--- a/test/tools/javac/enum/forwardRef/TestEnum3.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/forwardRef/TestEnum3.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2005, 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6209839
  * @summary Illegal forward reference to enum constants allowed by javac
  * @author  Peter von der Ah\u00e9
- * @compile/fail TestEnum3.java
+ * @compile/fail/ref=TestEnum3.out -XDrawDiagnostics  TestEnum3.java
  */
 
 enum TestEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/forwardRef/TestEnum3.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum3.java:13:34: compiler.err.illegal.enum.static.ref
+1 error
--- a/test/tools/javac/enum/forwardRef/TestEnum4.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/forwardRef/TestEnum4.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2005, 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6209839
  * @summary Illegal forward reference to enum constants allowed by javac
  * @author  Peter von der Ah\u00e9
- * @compile/fail TestEnum4.java
+ * @compile/fail/ref=TestEnum4.out -XDrawDiagnostics  TestEnum4.java
  */
 
 enum TestEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/forwardRef/TestEnum4.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum4.java:14:24: compiler.err.illegal.enum.static.ref
+1 error
--- a/test/tools/javac/enum/forwardRef/TestEnum5.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/forwardRef/TestEnum5.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2005, 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6209839
  * @summary Illegal forward reference to enum constants allowed by javac
  * @author  Peter von der Ah\u00e9
- * @compile/fail TestEnum5.java
+ * @compile/fail/ref=TestEnum5.out -XDrawDiagnostics  TestEnum5.java
  */
 
 enum TestEnum {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/forwardRef/TestEnum5.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum5.java:15:20: compiler.err.illegal.enum.static.ref
+1 error
--- a/test/tools/javac/enum/forwardRef/TestEnum6.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/enum/forwardRef/TestEnum6.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2006, 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
+ * @test    /nodynamiccopyright/
  * @bug     6424491
  * @summary Cannot initialise nested enums
  * @author  Peter von der Ah\u00e9
- * @compile/fail TestEnum6.java
+ * @compile/fail/ref=TestEnum6.out -XDrawDiagnostics  TestEnum6.java
  */
 
 public enum TestEnum6 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/forwardRef/TestEnum6.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum6.java:10:18: compiler.err.illegal.self.ref
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/8043926/T8043926.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, 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 8043926
+ * @summary javac, code valid in 7 is not compiling for 8
+ * @compile T8043926.java
+ */
+class T8043926 {
+    interface Iface<T1> {}
+
+    static class Impl implements Iface<Impl> {}
+
+    static class Acceptor<T2 extends Iface<T2>> {
+        public Acceptor(T2 obj) {}
+    }
+
+    void test(Impl impl) {
+        Acceptor<?> acceptor1 = new Acceptor<>(impl);
+        Acceptor<? extends Object> acceptor2 = new Acceptor<>(impl);
+    }
+}
--- a/test/tools/javac/implicitThis/NewBeforeOuterConstructed.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/implicitThis/NewBeforeOuterConstructed.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 1999, 2002, 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
+ * @test /nodynamiccopyright/
  * @bug 4249111
  * @summary 'new' of inner class should not be allowed unless outer is constructed
  *
- * @compile/fail NewBeforeOuterConstructed.java
+ * @compile/fail/ref=NewBeforeOuterConstructed.out -XDrawDiagnostics  NewBeforeOuterConstructed.java
  */
 
 import java.io.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/implicitThis/NewBeforeOuterConstructed.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NewBeforeOuterConstructed.java:27:21: compiler.err.cant.ref.before.ctor.called: this
+1 error
--- a/test/tools/javac/implicitThis/NewBeforeOuterConstructed2.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/implicitThis/NewBeforeOuterConstructed2.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
 /*
- * Copyright (c) 2002, 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
+ * @test /nodynamiccopyright/
  * @bug 4689058
  * @summary unverifiable code for implicit outer in super constructor call
  *
- * @compile/fail NewBeforeOuterConstructed2.java
+ * @compile/fail/ref=NewBeforeOuterConstructed2.out -XDrawDiagnostics  NewBeforeOuterConstructed2.java
  */
 
 public class NewBeforeOuterConstructed2 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/implicitThis/NewBeforeOuterConstructed2.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NewBeforeOuterConstructed2.java:20:35: compiler.err.cant.ref.before.ctor.called: this
+1 error
--- a/test/tools/javac/importChecks/ImportCanonical1.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/importChecks/ImportCanonical1.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2002, 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
+ * @test /nodynamiccopyright/
  * @bug 4462745
  * @summary compiler permits to import class given by its non-canonical name
  * @author gafter
  *
- * @compile/fail ImportCanonical1.java ImportCanonical2.java
+ * @compile/fail/ref=ImportCanonical1.out -XDrawDiagnostics  ImportCanonical1.java ImportCanonical2.java
  */
 
 package p1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importChecks/ImportCanonical1.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+ImportCanonical2.java:25:13: compiler.err.import.requires.canonical: p1.A1.I
+1 error
--- a/test/tools/javac/importChecks/ImportIsFullyQualified.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/importChecks/ImportIsFullyQualified.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2000, 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
+ * @test /nodynamiccopyright/
  * @bug 4335264
  * @summary Verify that import-on-demand must be fully qualified.
  * @author maddox
  *
- * @compile/fail ImportIsFullyQualified.java
+ * @compile/fail/ref=ImportIsFullyQualified.out -XDrawDiagnostics  ImportIsFullyQualified.java
  */
 
 import java.awt.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importChecks/ImportIsFullyQualified.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+ImportIsFullyQualified.java:11:1: compiler.err.doesnt.exist: JobAttributes
+1 error
--- a/test/tools/javac/importChecks/InvalidImportsNoClasses.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/importChecks/InvalidImportsNoClasses.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
 /*
- * Copyright (c) 2000, 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
+ * @test /nodynamiccopyright/
  * @bug 4312063
  * @summary Verify that nonexistent imports detected when no classes declared in compilation unit.
  * @author maddox
  *
- * @compile/fail InvalidImportsNoClasses.java
+ * @compile/fail/ref=InvalidImportsNoClasses.out -XDrawDiagnostics  InvalidImportsNoClasses.java
  */
 
 import nonexistent.pack.cls;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importChecks/InvalidImportsNoClasses.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+InvalidImportsNoClasses.java:10:24: compiler.err.doesnt.exist: nonexistent.pack
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importOnDemand/ImportOnDemandConflicts.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+/* @test /nodynamiccopyright/
+ * @compile/fail/ref=ImportOnDemandConflicts.out -XDrawDiagnostics p1/Object.java p1/String.java p2/Boolean.java
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importOnDemand/ImportOnDemandConflicts.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+String.java:13:9: compiler.err.ref.ambiguous: Boolean, kindname.class, p2.Boolean, p2, kindname.class, java.lang.Boolean, java.lang
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importOnDemand/p1/Object.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,5 @@
+package p1;
+
+public class Object {
+    public static void test() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importOnDemand/p1/String.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,15 @@
+package p1;
+
+import p2.*;
+
+public class String {
+    public static void test() { }
+}
+
+class Test1 {
+    private void test() {
+        String.test();
+        Object.test();
+        Boolean.valueOf(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/importOnDemand/p2/Boolean.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,7 @@
+package p2;
+
+public class Boolean {
+    public static Boolean valueOf(boolean b) {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest1.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest1.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest1 {
+    interface SAM<T> {
+        T action(T t);
+    }
+
+    <T> T m(SAM<T> op) {
+        return null;
+    }
+
+    class B {
+        B x() {
+            return this;
+        }
+    }
+
+    class C {}
+
+    void foo(B arg) {}
+    void foo(C arg) {}
+
+    void bar() {
+        foo(m(arg -> new B()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+IgnoreLambdaBodyDuringResolutionTest1.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.B), IgnoreLambdaBodyDuringResolutionTest1, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.C), IgnoreLambdaBodyDuringResolutionTest1
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest2.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest2.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest2 {
+    interface SAM<S> {
+        boolean test(S t);
+    }
+
+    <I, T extends I> I bar(final T l) {
+        return null;
+    }
+
+    class D<D1, D2> {
+        void foo() {
+            m(bar(e -> false));
+        }
+
+        void m(Class<D1> arg) {}
+        void m(SAM<D2> arg) {}
+    }
+
+    class F {
+        void foo() {
+            m(bar((String e) -> false));
+        }
+
+        <F1> void m(Class<F1> arg) {}
+        <F2> void m(SAM<F2> arg) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.out	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,6 @@
+IgnoreLambdaBodyDuringResolutionTest2.java:19:13: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Class<D1>), IgnoreLambdaBodyDuringResolutionTest2.D, kindname.method, m(IgnoreLambdaBodyDuringResolutionTest2.SAM<D2>), IgnoreLambdaBodyDuringResolutionTest2.D
+IgnoreLambdaBodyDuringResolutionTest2.java:19:18: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Object))
+IgnoreLambdaBodyDuringResolutionTest2.java:19:14: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Class<D1>, <any>, kindname.class, IgnoreLambdaBodyDuringResolutionTest2.D<D1,D2>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class)))
+IgnoreLambdaBodyDuringResolutionTest2.java:28:13: compiler.err.ref.ambiguous: m, kindname.method, <F1>m(java.lang.Class<F1>), IgnoreLambdaBodyDuringResolutionTest2.F, kindname.method, <F2>m(IgnoreLambdaBodyDuringResolutionTest2.SAM<F2>), IgnoreLambdaBodyDuringResolutionTest2.F
+IgnoreLambdaBodyDuringResolutionTest2.java:28:14: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class))
+5 errors
--- a/test/tools/javac/lib/DPrinter.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/lib/DPrinter.java	Thu Jul 10 12:39:26 2014 -0700
@@ -31,6 +31,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -337,6 +338,8 @@
             printList(label, (List) item);
         } else if (item instanceof Name) {
             printName(label, (Name) item);
+        } else if (item instanceof Scope) {
+            printScope(label, (Scope) item);
         } else {
             printString(label, String.valueOf(item));
         }
@@ -356,7 +359,7 @@
                     out.print(label);
                     out.print(": [");
                     String sep = "";
-                    for (Symbol sym: scope.getElements()) {
+                    for (Symbol sym: scope.getSymbols()) {
                         out.print(sep);
                         out.print(sym.name);
                         sep = ",";
@@ -370,19 +373,7 @@
                     out.println(label);
 
                     indent(+1);
-                    printImplClass(scope, Scope.class);
-                    printSymbol("owner", scope.owner, Details.SUMMARY);
-                    printScope("next", scope.next, Details.SUMMARY);
-                    printObject("shared", getField(scope, Scope.class, "shared"), Details.SUMMARY);
-                    if (scope instanceof CompoundScope) {
-                        printObject("subScopes",
-                                getField(scope, CompoundScope.class, "subScopes"),
-                                Details.FULL);
-                    } else {
-                        for (Symbol sym : scope.getElements()) {
-                            printSymbol(sym.name.toString(), sym, Details.SUMMARY);
-                        }
-                    }
+                    printFullScopeImpl(scope);
                     indent(-1);
                     break;
                 }
@@ -390,6 +381,72 @@
         }
     }
 
+    void printFullScopeImpl(Scope scope) {
+        indent();
+        out.println(scope.getClass().getName());
+        printSymbol("owner", scope.owner, Details.SUMMARY);
+        if (SCOPE_IMPL_CLASS.equals(scope.getClass().getName())) {
+            printScope("next", (Scope) getField(scope, scope.getClass(), "next"), Details.SUMMARY);
+            printObject("shared", getField(scope, scope.getClass(), "shared"), Details.SUMMARY);
+            Object[] table = (Object[]) getField(scope, scope.getClass(), "table");
+            for (int i = 0; i < table.length; i++) {
+                if (i > 0)
+                    out.print(", ");
+                else
+                    indent();
+                out.print(i + ":" + entryToString(table[i], table, false));
+            }
+            out.println();
+        } else if (FILTER_SCOPE_CLASS.equals(scope.getClass().getName())) {
+            printScope("delegate",
+                    (Scope) getField(scope, scope.getClass(), "delegate"), Details.FULL);
+        } else if (scope instanceof CompoundScope) {
+            printList("delegates", (List<?>) getField(scope, CompoundScope.class, "subScopes"));
+        } else {
+            for (Symbol sym : scope.getSymbols()) {
+                printSymbol(sym.name.toString(), sym, Details.SUMMARY);
+            }
+        }
+    }
+        //where:
+        static final String SCOPE_IMPL_CLASS = "com.sun.tools.javac.code.Scope$ScopeImpl";
+        static final String FILTER_SCOPE_CLASS = "com.sun.tools.javac.code.Scope$FilterImportScope";
+
+    /**
+     * Create a string showing the contents of an entry, using the table
+     * to help identify cross-references to other entries in the table.
+     * @param e the entry to be shown
+     * @param table the table containing the other entries
+     */
+    String entryToString(Object e, Object[] table, boolean ref) {
+        if (e == null)
+            return "null";
+        Symbol sym = (Symbol) getField(e, e.getClass(), "sym");
+        if (sym == null)
+            return "sent"; // sentinel
+        if (ref) {
+            int index = indexOf(table, e);
+            if (index != -1)
+                return String.valueOf(index);
+        }
+        Scope scope = (Scope) getField(e, e.getClass(), "scope");
+        return "(" + sym.name + ":" + sym
+                + ",shdw:" + entryToString(callMethod(e, e.getClass(), "next"), table, true)
+                + ",sibl:" + entryToString(getField(e, e.getClass(), "sibling"), table, true)
+                + ((sym.owner != scope.owner)
+                    ? (",BOGUS[" + sym.owner + "," + scope.owner + "]")
+                    : "")
+                + ")";
+    }
+
+    <T> int indexOf(T[] array, T item) {
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] == item)
+                return i;
+        }
+        return -1;
+    }
+
     public void printSource(String label, JCTree tree) {
         printString(label, Pretty.toSimpleString(tree, maxSrcLength));
     }
@@ -552,6 +609,23 @@
         }
     }
 
+    protected Object callMethod(Object o, Class<?> clazz, String name) {
+        try {
+            Method m = clazz.getDeclaredMethod(name);
+            boolean prev = m.isAccessible();
+            m.setAccessible(true);
+            try {
+                return m.invoke(o);
+            } finally {
+                m.setAccessible(prev);
+            }
+        } catch (ReflectiveOperationException e) {
+            return e;
+        } catch (SecurityException e) {
+            return e;
+        }
+    }
+
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="JCTree visitor methods">
--- a/test/tools/javac/scope/7017664/CompoundScopeTest.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/scope/7017664/CompoundScopeTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -117,13 +117,13 @@
                 boolean subAdded = false;
                 for (int sc = 0 ; sc < 3 ; sc ++) {
                     if (scopeNesting[sc][i]) {
-                        sub.addSubScope(scopes[sc]);
+                        sub.prependSubScope(scopes[sc]);
                         if (!subAdded) {
-                            root.addSubScope(sub);
+                            root.prependSubScope(sub);
                             subAdded = true;
                         }
                     } else {
-                        root.addSubScope(scopes[sc]);
+                        root.prependSubScope(scopes[sc]);
                     }
                 }
                 log("testing scope: " + root);
@@ -145,7 +145,7 @@
          * Create a scope containing a given number of synthetic symbols
          */
         Scope createScope(int nelems) {
-            Scope s = new Scope(symtab.noSymbol);
+            WriteableScope s = WriteableScope.create(symtab.noSymbol);
             for (int i = 0 ; i < nelems ; i++) {
                 Symbol sym = new TypeVariableSymbol(0, names.fromString("s" + i), null, null);
                 s.enter(sym);
@@ -181,7 +181,7 @@
                     elems :
                     filter(elems, sf);
             int expectedCount = allSymbols.length();
-            for (Symbol s : sf == null ? cs.getElements() : cs.getElements(sf)) {
+            for (Symbol s : sf == null ? cs.getSymbols() : cs.getSymbols(sf)) {
                 checkSameSymbols(s, allSymbols.head);
                 allSymbols = allSymbols.tail;
                 found.append(s);
@@ -204,7 +204,7 @@
                     filter(shadowedEntry.getValue(), sf);
                 int expectedCount = shadowed.length();
                 Name name = shadowedEntry.getKey();
-                for (Symbol s : sf == null ? cs.getElementsByName(name) : cs.getElementsByName(name, sf)) {
+                for (Symbol s : sf == null ? cs.getSymbolsByName(name) : cs.getSymbolsByName(name, sf)) {
                     checkSameSymbols(s, shadowed.head);
                     shadowed = shadowed.tail;
                     count++;
--- a/test/tools/javac/scope/7017664/ImplementationCacheTest.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/scope/7017664/ImplementationCacheTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, 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
@@ -98,7 +98,7 @@
 
         MethodSymbol I_m = null;
 
-        for (Symbol sym : i.members().getElements()) {
+        for (Symbol sym : i.members().getSymbols()) {
             if (sym.name.contentEquals("m")) {
                 I_m = (MethodSymbol)sym;
             }
--- a/test/tools/javac/scope/HashCollisionTest.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/scope/HashCollisionTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, 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
@@ -25,16 +25,21 @@
  * @test
  * @bug 7004029
  * @summary Ensure Scope impl can cope with hash collisions
+ * @library /tools/javac/lib
+ * @build DPrinter HashCollisionTest
+ * @run main HashCollisionTest
  */
 
 import java.lang.reflect.*;
 import java.io.*;
+
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTrees;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Scope.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.file.JavacFileManager;
-import static com.sun.tools.javac.code.Kinds.*;
 
 public class HashCollisionTest {
     public static void main(String... args) throws Exception {
@@ -47,12 +52,13 @@
         JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
         names = Names.instance(context);       // Name.Table impls tied to an instance of Names
         symtab = Symtab.instance(context);
+        trees = JavacTrees.instance(context);
 
         // determine hashMask for an empty scope
-        Scope emptyScope = new Scope(symtab.unnamedPackage); // any owner will do
-        Field sHashMask = Scope.class.getDeclaredField("hashMask");
-        sHashMask.setAccessible(true);
-        scopeHashMask = sHashMask.getInt(emptyScope);
+        Scope emptyScope = WriteableScope.create(symtab.unnamedPackage); // any owner will do
+        Field field = emptyScope.getClass().getDeclaredField("hashMask");
+        field.setAccessible(true);
+        scopeHashMask = field.getInt(emptyScope);
         log("scopeHashMask: " + scopeHashMask);
 
         // 1. determine the Name.hashCode of "Entry", and therefore the index of
@@ -92,7 +98,7 @@
 
         // 4. Create a package containing a nested class using the name from 2
         PackageSymbol p = new PackageSymbol(names.fromString("p"), symtab.rootPackage);
-        p.members_field = new Scope(p);
+        p.members_field = WriteableScope.create(p);
         ClassSymbol inner = createClass(innerName, p);
         // we'll need this later when we "rename" cn
         ClassSymbol outer = createClass(outerName, p);
@@ -100,42 +106,25 @@
         // 5. Create a star-import scope
         log ("createStarImportScope");
 
-        // if StarImportScope exists, use it, otherwise, for testing legacy code,
-        // fall back on ImportScope
-        Scope starImportScope;
-        Method importAll;
         PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
-        try {
-            Class<?> c = Class.forName("com.sun.tools.javac.code.Scope$StarImportScope");
-            Constructor ctor = c.getDeclaredConstructor(new Class[] { Symbol.class });
-            importAll = c.getDeclaredMethod("importAll", new Class[] { Scope.class });
-            starImportScope = (Scope) ctor.newInstance(new Object[] { pkg });
-        } catch (ClassNotFoundException e) {
-            starImportScope = new ImportScope(pkg);
-            importAll = null;
-        }
+        StarImportScope starImportScope = new StarImportScope(pkg);
 
         dump("initial", starImportScope);
 
         // 6. Insert the contents of the package from 4.
-        Scope p_members = p.members();
-        if (importAll != null) {
-            importAll.invoke(starImportScope, p_members);
-        } else {
-            Scope fromScope = p_members;
-            Scope toScope = starImportScope;
-            // The following lines are taken from MemberEnter.importAll,
-            // before the use of StarImportScope.importAll.
-            for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
-                if (e.sym.kind == TYP && !toScope.includes(e.sym))
-                    toScope.enter(e.sym, fromScope);
+        Scope fromScope = p.members();
+        ImportFilter typeFilter = new ImportFilter() {
+            @Override
+            public boolean accepts(Scope origin, Symbol sym) {
+                return sym.kind == Kinds.TYP;
             }
-        }
+        };
+        starImportScope.importAll(fromScope, fromScope, typeFilter, false);
 
         dump("imported p", starImportScope);
 
         // 7. Insert the class from 3.
-        starImportScope.enter(ce, cc.members_field);
+        starImportScope.importAll(cc.members_field, cc.members_field, typeFilter, false);
         dump("imported ce", starImportScope);
 
         /*
@@ -149,11 +138,11 @@
         outer.members_field.enter(inner);
 
         // 9. Lookup Entry
-        Scope.Entry e = starImportScope.lookup(entry);
+        Symbol found = starImportScope.findFirst(entry);
+        if (found != ce)
+            throw new Exception("correct symbol not found: " + entry + "; found=" + found);
+
         dump("final", starImportScope);
-
-        if (e.sym == null)
-            throw new Exception("symbol not found: " + entry);
     }
 
     /*
@@ -170,7 +159,7 @@
      */
     ClassSymbol createClass(Name name, Symbol owner) {
         ClassSymbol sym = new ClassSymbol(0, name, owner);
-        sym.members_field = new Scope(sym);
+        sym.members_field = WriteableScope.create(sym);
         if (owner != symtab.unnamedPackage)
             owner.members().enter(sym);
         return sym;
@@ -180,58 +169,16 @@
      * Dump the contents of a scope to System.err.
      */
     void dump(String label, Scope s) throws Exception {
-        dump(label, s, System.err);
+        PrintWriter pw = new PrintWriter(System.err);
+        new DPrinter(pw, trees).printScope(label, s);
+        pw.flush();
     }
 
-    /**
-     * Dump the contents of a scope to a stream.
-     */
-    void dump(String label, Scope s, PrintStream out) throws Exception {
-        out.println(label);
-        Field sTable = Scope.class.getDeclaredField("table");
-        sTable.setAccessible(true);
+    Object readField(Object scope, String fieldName) throws Exception {
+        Field field = scope.getClass().getDeclaredField(fieldName);
+        field.setAccessible(true);
 
-        out.println("owner:" + s.owner);
-        Scope.Entry[] table = (Scope.Entry[]) sTable.get(s);
-        for (int i = 0; i < table.length; i++) {
-            if (i > 0)
-                out.print(", ");
-            out.print(i + ":" + toString(table[i], table, false));
-        }
-        out.println();
-    }
-
-    /**
-     * Create a string showing the contents of an entry, using the table
-     * to help identify cross-references to other entries in the table.
-     * @param e the entry to be shown
-     * @param table the table containing the other entries
-     */
-    String toString(Scope.Entry e, Scope.Entry[] table, boolean ref) {
-        if (e == null)
-            return "null";
-        if (e.sym == null)
-            return "sent"; // sentinel
-        if (ref) {
-            int index = indexOf(table, e);
-            if (index != -1)
-                return String.valueOf(index);
-        }
-        return "(" + e.sym.name + ":" + e.sym
-                + ",shdw:" + toString(e.next(), table, true)
-                + ",sibl:" + toString(e.sibling, table, true)
-                + ((e.sym.owner != e.scope.owner)
-                    ? (",BOGUS[" + e.sym.owner + "," + e.scope.owner + "]")
-                    : "")
-                + ")";
-    }
-
-    <T> int indexOf(T[] array, T item) {
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == item)
-                return i;
-        }
-        return -1;
+        return field.get(scope);
     }
 
     /**
@@ -246,4 +193,5 @@
 
     Names names;
     Symtab symtab;
+    Trees trees;
 }
--- a/test/tools/javac/scope/StarImportTest.java	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/scope/StarImportTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, 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
@@ -27,14 +27,17 @@
  * @summary Basher for star-import scopes
  */
 
-import java.lang.reflect.*;
 import java.util.*;
 import java.util.List;
-import com.sun.tools.javac.util.*;
+
 import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.code.Scope.*;
+import com.sun.tools.javac.code.Scope.ImportFilter;
+import com.sun.tools.javac.code.Scope.StarImportScope;
+import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.*;
+
 import static com.sun.tools.javac.code.Kinds.*;
 
 public class StarImportTest {
@@ -87,13 +90,9 @@
         System.err.print(msg);
         System.err.print(": ");
         String sep = "(";
-        for (Scope.Entry se = s.elems; se != null; se = se.sibling) {
-            for (Scope.Entry e = se; e.sym != null; e = e.next()) {
-                System.err.print(sep + e.sym.name + ":" + e.sym);
-                sep = ",";
-            }
-            System.err.print(")");
-            sep = ", (";
+        for (Symbol sym : s.getSymbols()) {
+            System.err.print(sep + sym.name + ":" + sym);
+            sep = ",";
         }
         System.err.println();
     }
@@ -171,7 +170,7 @@
             int count = rgen.nextInt(MAX_SETUP_PACKAGE_COUNT);
             log("setup: creating package " + name + " with " + count + " entries");
             PackageSymbol p = new PackageSymbol(name, symtab.rootPackage);
-            p.members_field = new Scope(p);
+            p.members_field = WriteableScope.create(p);
             for (int i = 0; i < count; i++) {
                 String outer = name + "c" + i;
                 String suffix = random(null, "$Entry", "$Entry2");
@@ -213,38 +212,21 @@
             log ("createStarImportScope");
             PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
 
-            // if StarImportScope exists, use it, otherwise, for testing legacy code,
-            // fall back on ImportScope
-            Method importAll;
-            try {
-                Class<?> c = Class.forName("com.sun.tools.javac.code.Scope$StarImportScope");
-                Constructor ctor = c.getDeclaredConstructor(new Class[] { Symbol.class });
-                importAll = c.getDeclaredMethod("importAll", new Class[] { Scope.class });
-                starImportScope = (Scope) ctor.newInstance(new Object[] { pkg });
-            } catch (ClassNotFoundException e) {
-                starImportScope = new ImportScope(pkg);
-                importAll = null;
-            }
+            starImportScope = new StarImportScope(pkg);
             starImportModel = new Model();
 
             for (Symbol imp: imports) {
                 Scope members = imp.members();
-                if (importAll != null) {
 //                    log("importAll", members);
-                    importAll.invoke(starImportScope, members);
-                } else {
-                    Scope fromScope = members;
-                    Scope toScope = starImportScope;
-                    // The following lines are taken from MemberEnter.importAll,
-                    // before the use of StarImportScope.importAll.
-                    for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
-                        if (e.sym.kind == TYP && !toScope.includes(e.sym))
-                            toScope.enter(e.sym, fromScope);
+                starImportScope.importAll(members, members, new ImportFilter() {
+                    @Override
+                    public boolean accepts(Scope origin, Symbol t) {
+                        return t.kind == TYP;
                     }
-                }
+                }, false);
 
-                for (Scope.Entry e = members.elems; e != null; e = e.sibling) {
-                    starImportModel.enter(e.sym);
+                for (Symbol sym : members.getSymbols()) {
+                    starImportModel.enter(sym);
                 }
             }
 
@@ -260,9 +242,9 @@
             log ("test");
             List<ClassSymbol> nestedClasses = new LinkedList<ClassSymbol>();
             for (PackageSymbol p: packages) {
-                for (Scope.Entry se = p.members_field.elems; se != null; se = se.sibling) {
-                    if (se.sym.name.toString().contains("$"))
-                        nestedClasses.add((ClassSymbol) se.sym);
+                for (Symbol sym : p.members_field.getSymbols()) {
+                    if (sym.name.toString().contains("$"))
+                        nestedClasses.add((ClassSymbol) sym);
                 }
             }
 
@@ -283,8 +265,7 @@
                 // determine new owner
                 Name outerName = names.fromString(s.substring(0, dollar));
 //                log(sym + " owner: " + sym.owner, sym.owner.members());
-                Scope.Entry outerEntry = sym.owner.members().lookup(outerName);
-                ClassSymbol outer = (ClassSymbol) outerEntry.sym;
+                ClassSymbol outer = (ClassSymbol)sym.owner.members().findFirst(outerName);
 //                log("outer: " + outerName + " " + outer);
 
                 // remove from package
@@ -302,7 +283,7 @@
 
         ClassSymbol createClass(Name name, Symbol owner) {
             ClassSymbol sym = new ClassSymbol(0, name, owner);
-            sym.members_field = new Scope(sym);
+            sym.members_field = WriteableScope.create(sym);
             if (owner != symtab.unnamedPackage)
                 owner.members().enter(sym);
             return sym;
@@ -318,7 +299,7 @@
         List<Symbol> imports = new ArrayList<Symbol>();
         int nextClassSerial;
 
-        Scope starImportScope;
+        StarImportScope starImportScope;
         Model starImportModel;
     }
 
@@ -355,9 +336,8 @@
         void check(Scope scope) {
             // First, check all entries in scope are in map
             int bogusCount = 0;
-            for (Scope.Entry se = scope.elems; se != null; se = se.sibling) {
-                Symbol sym = se.sym;
-                if (sym.owner != se.scope.owner) {
+            for (Symbol sym : scope.getSymbols()) {
+                if (sym.owner != scope.getOrigin(sym).owner) {
                     if (bogus.contains(sym)) {
                         bogusCount++;
                     } else {
@@ -380,16 +360,14 @@
             // Second, check all entries in map are in scope
             for (Map.Entry<Name,Set<Symbol>> me: map.entrySet()) {
                 Name name = me.getKey();
-                Scope.Entry se = scope.lookup(name);
-                assert (se != null);
-                if (se.sym == null) {
+                if (scope.findFirst(name) == null) {
                     error("check: no entries found for " + name + " in scope");
                     continue;
                 }
             nextSym:
                 for (Symbol sym: me.getValue()) {
-                    for (Scope.Entry e = se; e.sym != null; e = e.next()) {
-                        if (sym == e.sym)
+                    for (Symbol s : scope.getSymbolsByName(name)) {
+                        if (sym == s)
                             continue nextSym;
                     }
                     error("check: symbol " + sym + " not found in scope");
--- a/test/tools/javac/staticImport/6537020/T6537020.out	Thu Jul 10 12:13:35 2014 -0700
+++ b/test/tools/javac/staticImport/6537020/T6537020.out	Thu Jul 10 12:39:26 2014 -0700
@@ -1,2 +1,2 @@
-T6537020.java:25:16: compiler.err.ref.ambiguous: s, kindname.variable, s, p.T6537020.B, kindname.variable, s, p.T6537020.A
+T6537020.java:25:16: compiler.err.ref.ambiguous: s, kindname.variable, s, p.T6537020.A, kindname.variable, s, p.T6537020.B
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/tree/MakeTypeTest.java	Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2014, 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     8042239
+ * @summary Verify that TreeMaker.Type(Type) can handle all reasonable types
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor MakeTypeTest
+ * @compile/process/ref=MakeTypeTest.out -processor MakeTypeTest MakeTypeTest.java
+ */
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.List;
+
+public class MakeTypeTest extends JavacTestingAbstractProcessor {
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (!roundEnv.processingOver())
+            return false;
+
+        JavacTask.instance(processingEnv).addTaskListener(new TaskListener() {
+            @Override
+            public void started(TaskEvent e) {
+            }
+            @Override
+            public void finished(TaskEvent e) {
+                if (e.getKind() == TaskEvent.Kind.ANALYZE &&
+                    e.getTypeElement().getQualifiedName().contentEquals("MakeTypeTest")) {
+                    doTest();
+                }
+            }
+        });
+
+        return false;
+    }
+
+    void doTest() {
+        //go through this file, look for @TestType and verify TreeMaker.Type behavior:
+        Context ctx = ((JavacProcessingEnvironment) processingEnv).getContext();
+        JavacTrees trees = JavacTrees.instance(ctx);
+        TypeElement testType = processingEnv.getElementUtils().getTypeElement("MakeTypeTest");
+        TreePath path = trees.getPath(testType);
+
+        Set<TypeKind> unseenTypeKinds = EnumSet.allOf(TypeKind.class);
+
+        new TreePathScanner<Void, Void>() {
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                handleDecl(new TreePath(getCurrentPath(), node.getType()));
+                return super.visitVariable(node, p);
+            }
+
+            @Override
+            public Void visitMethod(MethodTree node, Void p) {
+                if (node.getReturnType() != null)
+                    handleDecl(new TreePath(getCurrentPath(), node.getReturnType()));
+                return super.visitMethod(node, p);
+            }
+
+            @Override
+            public Void visitTypeParameter(TypeParameterTree node, Void p) {
+                TypeVariable type = (TypeVariable) trees.getTypeMirror(getCurrentPath());
+                TreePath aBoundPath = new TreePath(getCurrentPath(), node.getBounds().get(0));
+                handleDecl(aBoundPath, (Type) type.getUpperBound());
+                return super.visitTypeParameter(node, p);
+            }
+
+            void handleDecl(TreePath typePath) {
+                handleDecl(typePath, (Type) trees.getTypeMirror(typePath));
+            }
+
+            void handleDecl(TreePath typePath, Type type) {
+                Element decl = trees.getElement(typePath.getParentPath());
+                TestType testType = decl.getAnnotation(TestType.class);
+
+                if (testType == null) return ;
+
+                if (testType.nested() >= 0) {
+                    ClassType ct = (ClassType) type;
+                    type = ct.getTypeArguments().get(testType.nested());
+                }
+
+                JCExpression typeExpr = TreeMaker.instance(ctx).Type(type);
+
+                if (!typeExpr.getKind().equals(testType.expectedKind())) {
+                    throw new IllegalStateException("was=" + typeExpr + ", kind=" +
+                            typeExpr.getKind() + "; expected kind: " +
+                            testType.expectedKind() + "; type=" + type);
+                }
+                unseenTypeKinds.remove(type.getKind());
+            }
+
+        }.scan(path, null);
+
+        unseenTypeKinds.removeAll(Arrays.asList(TypeKind.NONE, TypeKind.NULL, TypeKind.ERROR,
+                TypeKind.PACKAGE, TypeKind.EXECUTABLE, TypeKind.OTHER));
+
+        if (!unseenTypeKinds.isEmpty())
+            throw new IllegalStateException("Unhandled types=" + unseenTypeKinds);
+
+        System.err.println("done.");
+    }
+
+    //the following defines the Types that should be passed into TreeMaker.Type and
+    //the expected resulting Tree kind:
+
+    @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+    boolean f1;
+    @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+    byte f2;
+    @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+    char f3;