Merge
authorlana
Fri, 20 Jan 2017 19:10:00 +0000
changeset 43275 b73702608fc6
parent 43168 8c70d170e62c (current diff)
parent 43273 2614e1907a0b (diff)
child 43276 0f8dd574fa0a
Merge
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java	Fri Jan 20 19:10:00 2017 +0000
@@ -68,8 +68,8 @@
  * javax.lang.model.*} packages bundled in Java SE 8 were required to
  * also be runnable on Java SE 7.  Therefore, default methods
  * were <em>not</em> used when extending {@code javax.lang.model.*}
- * to cover Java SE 8 language features.  However, default methods may
- * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * to cover Java SE 8 language features.  However, default methods
+ * are used in subsequent revisions of the {@code javax.lang.model.*}
  * packages that are only required to run on Java SE 8 and higher
  * platform versions.
  *
@@ -90,11 +90,16 @@
     R visit(AnnotationValue av, P p);
 
     /**
-     * A convenience method equivalent to {@code v.visit(av, null)}.
+     * A convenience method equivalent to {@code visit(av, null)}.
+     *
+     * @implSpec The default implementation is {@code visit(av, null)}.
+     *
      * @param av the value to visit
      * @return  a visitor-specified result
      */
-    R visit(AnnotationValue av);
+    default R visit(AnnotationValue av) {
+        return visit(av, null);
+    }
 
     /**
      * Visits a {@code boolean} value in an annotation.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java	Fri Jan 20 19:10:00 2017 +0000
@@ -59,8 +59,8 @@
  * javax.lang.model.*} packages bundled in Java SE 8 were required to
  * also be runnable on Java SE 7.  Therefore, default methods
  * were <em>not</em> used when extending {@code javax.lang.model.*}
- * to cover Java SE 8 language features.  However, default methods may
- * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * to cover Java SE 8 language features.  However, default methods
+ * are used in subsequent revisions of the {@code javax.lang.model.*}
  * packages that are only required to run on Java SE 8 and higher
  * platform versions.
  *
@@ -85,11 +85,16 @@
     R visit(Element e, P p);
 
     /**
-     * A convenience method equivalent to {@code v.visit(e, null)}.
+     * A convenience method equivalent to {@code visit(e, null)}.
+     *
+     * @implSpec The default implementation is {@code visit(e, null)}.
+     *
      * @param e  the element to visit
      * @return a visitor-specified result
      */
-    R visit(Element e);
+    default R visit(Element e) {
+        return visit(e, null);
+    }
 
     /**
      * Visits a package element.
@@ -146,10 +151,16 @@
 
     /**
      * Visits a module element.
+     *
+     * @implSpec Visits a {@code ModuleElement} by calling {@code
+     * visitUnknown(e, p)}.
+     *
      * @param e  the element to visit
      * @param p  a visitor-specified parameter
      * @return a visitor-specified result
      * @since 9
      */
-    R visitModule(ModuleElement e, P p);
+    default R visitModule(ModuleElement e, P p) {
+        return visitUnknown(e, p);
+    }
 }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java	Fri Jan 20 19:10:00 2017 +0000
@@ -59,8 +59,8 @@
  * javax.lang.model.*} packages bundled in Java SE 8 were required to
  * also be runnable on Java SE 7.  Therefore, default methods
  * were <em>not</em> used when extending {@code javax.lang.model.*}
- * to cover Java SE 8 language features.  However, default methods may
- * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * to cover Java SE 8 language features.  However, default methods
+ * are used in subsequent revisions of the {@code javax.lang.model.*}
  * packages that are only required to run on Java SE 8 and higher
  * platform versions.
  *
@@ -85,11 +85,16 @@
     R visit(TypeMirror t, P p);
 
     /**
-     * A convenience method equivalent to {@code v.visit(t, null)}.
+     * A convenience method equivalent to {@code visit(t, null)}.
+     *
+     * @implSpec The default implementation is {@code visit(t, null)}.
+     *
      * @param t the element to visit
      * @return  a visitor-specified result
      */
-    R visit(TypeMirror t);
+    default R visit(TypeMirror t) {
+        return visit(t, null);
+    }
 
     /**
      * Visits a primitive type.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -65,17 +65,17 @@
  * @see AbstractAnnotationValueVisitor8
  * @see AbstractAnnotationValueVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public abstract class AbstractAnnotationValueVisitor6<R, P>
     implements AnnotationValueVisitor<R, P> {
 
     /**
      * Constructor for concrete subclasses to call.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected AbstractAnnotationValueVisitor6() {}
 
     /**
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -59,13 +59,13 @@
  * @see AbstractAnnotationValueVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public abstract class AbstractAnnotationValueVisitor7<R, P> extends AbstractAnnotationValueVisitor6<R, P> {
 
     /**
      * Constructor for concrete subclasses to call.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected AbstractAnnotationValueVisitor7() {
         super();
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -67,15 +67,15 @@
  * @see AbstractElementVisitor8
  * @see AbstractElementVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R, P> {
     /**
      * Constructor for concrete subclasses to call.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected AbstractElementVisitor6(){}
 
     /**
@@ -139,6 +139,7 @@
      */
     @Override
     public R visitModule(ModuleElement e, P p) {
-        return visitUnknown(e, p);
+        // Use implementation from interface default method
+        return ElementVisitor.super.visitModule(e, p);
     }
 }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -63,12 +63,12 @@
  * @see AbstractElementVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public abstract class AbstractElementVisitor7<R, P> extends AbstractElementVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses to call.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected AbstractElementVisitor7(){
         super();
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -66,15 +66,15 @@
  * @see AbstractTypeVisitor8
  * @see AbstractTypeVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {
     /**
      * Constructor for concrete subclasses to call.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected AbstractTypeVisitor6() {}
 
     /**
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -63,12 +63,12 @@
  * @see AbstractTypeVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public abstract class AbstractTypeVisitor7<R, P> extends AbstractTypeVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses to call.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected AbstractTypeVisitor7() {
         super();
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -81,17 +81,17 @@
  * @see ElementKindVisitor8
  * @see ElementKindVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public class ElementKindVisitor6<R, P>
                   extends SimpleElementVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected ElementKindVisitor6() {
         super(null);
     }
@@ -101,7 +101,10 @@
      * default value.
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected ElementKindVisitor6(R defaultValue) {
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -76,13 +76,13 @@
  * @see ElementKindVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected ElementKindVisitor7() {
         super(null);
     }
@@ -93,6 +93,7 @@
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected ElementKindVisitor7(R defaultValue) {
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -92,10 +92,7 @@
  * @see ElementScanner8
  * @see ElementScanner9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
     /**
@@ -106,7 +103,10 @@
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected ElementScanner6(){
         DEFAULT_VALUE = null;
     }
@@ -116,7 +116,10 @@
      * default value.
      *
      * @param defaultValue the default value
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected ElementScanner6(R defaultValue){
         DEFAULT_VALUE = defaultValue;
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -89,13 +89,13 @@
  * @see ElementScanner9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public class ElementScanner7<R, P> extends ElementScanner6<R, P> {
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected ElementScanner7(){
         super(null);
     }
@@ -106,6 +106,7 @@
      *
      * @param defaultValue the default value
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected ElementScanner7(R defaultValue){
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -74,10 +74,7 @@
  * @see SimpleAnnotationValueVisitor8
  * @see SimpleAnnotationValueVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public class SimpleAnnotationValueVisitor6<R, P>
     extends AbstractAnnotationValueVisitor6<R, P> {
@@ -92,7 +89,10 @@
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected SimpleAnnotationValueVisitor6() {
         super();
         DEFAULT_VALUE = null;
@@ -103,7 +103,10 @@
      * default value.
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected SimpleAnnotationValueVisitor6(R defaultValue) {
         super();
         DEFAULT_VALUE = defaultValue;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -66,13 +66,13 @@
  * @see SimpleAnnotationValueVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public class SimpleAnnotationValueVisitor7<R, P> extends SimpleAnnotationValueVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected SimpleAnnotationValueVisitor7() {
         super(null);
     }
@@ -83,6 +83,7 @@
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected SimpleAnnotationValueVisitor7(R defaultValue) {
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -78,10 +78,7 @@
  * @see SimpleElementVisitor8
  * @see SimpleElementVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
     /**
@@ -94,7 +91,10 @@
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected SimpleElementVisitor6(){
         DEFAULT_VALUE = null;
     }
@@ -104,7 +104,10 @@
      * default value.
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected SimpleElementVisitor6(R defaultValue){
         DEFAULT_VALUE = defaultValue;
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -72,13 +72,13 @@
  * @see SimpleElementVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected SimpleElementVisitor7(){
         super(null);
     }
@@ -89,6 +89,7 @@
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected SimpleElementVisitor7(R defaultValue){
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -78,10 +78,7 @@
  * @see SimpleTypeVisitor8
  * @see SimpleTypeVisitor9
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public class SimpleTypeVisitor6<R, P> extends AbstractTypeVisitor6<R, P> {
     /**
@@ -94,7 +91,10 @@
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected SimpleTypeVisitor6(){
         DEFAULT_VALUE = null;
     }
@@ -104,7 +104,10 @@
      * default value.
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected SimpleTypeVisitor6(R defaultValue){
         DEFAULT_VALUE = defaultValue;
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -72,13 +72,13 @@
  * @see SimpleTypeVisitor9
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public class SimpleTypeVisitor7<R, P> extends SimpleTypeVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses; uses {@code null} for the
      * default value.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected SimpleTypeVisitor7(){
         super(null);
     }
@@ -89,6 +89,7 @@
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected SimpleTypeVisitor7(R defaultValue){
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java	Fri Jan 20 19:10:00 2017 +0000
@@ -76,16 +76,16 @@
  * @see TypeKindVisitor7
  * @see TypeKindVisitor8
  * @since 1.6
- * @deprecated Release 6 is obsolete; update to a visitor for a newer
- * release level.
  */
-@Deprecated
 @SupportedSourceVersion(RELEASE_6)
 public class TypeKindVisitor6<R, P> extends SimpleTypeVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses to call; uses {@code null}
      * for the default value.
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected TypeKindVisitor6() {
         super(null);
     }
@@ -96,7 +96,10 @@
      * for the default value.
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
+     * @deprecated Release 6 is obsolete; update to a visitor for a newer
+     * release level.
      */
+    @Deprecated
     protected TypeKindVisitor6(R defaultValue) {
         super(defaultValue);
     }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor7.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor7.java	Fri Jan 20 19:10:00 2017 +0000
@@ -73,13 +73,13 @@
  * @see TypeKindVisitor8
  * @since 1.7
  */
-@SuppressWarnings("deprecation") // Superclass deprecated
 @SupportedSourceVersion(RELEASE_7)
 public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {
     /**
      * Constructor for concrete subclasses to call; uses {@code null}
      * for the default value.
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected TypeKindVisitor7() {
         super(null);
     }
@@ -90,6 +90,7 @@
      *
      * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
      */
+    @SuppressWarnings("deprecation") // Superclass constructor deprecated
     protected TypeKindVisitor7(R defaultValue) {
         super(defaultValue);
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTreePath.java	Fri Jan 20 19:10:00 2017 +0000
@@ -98,7 +98,7 @@
      * @param t the DocCommentTree to create the path for.
      */
     public DocTreePath(TreePath treePath, DocCommentTree t) {
-        this.treePath = Objects.requireNonNull(treePath);
+        this.treePath = treePath;
         this.docComment = Objects.requireNonNull(t);
         this.parent = null;
         this.leaf = t;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -31,6 +31,7 @@
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
 import javax.tools.Diagnostic;
 import javax.tools.FileObject;
 import javax.tools.JavaCompiler.CompilationTask;
@@ -127,17 +128,22 @@
 
     /**
      * Returns a doc tree path containing the doc comment tree of the given file.
-     * The file must be an HTML file, in which case the doc comment tree represents the
-     * contents of the &lt;body&gt; tag, and any enclosing tags are ignored.
+     * The file must be an HTML file, in which case the doc comment tree represents
+     * the contents of the {@code <body>} tag, and any enclosing tags are ignored.
+     * Any references to source code elements contained in {@code @see} and
+     * {@code {@link}} tags in the doc comment tree will be evaluated in the
+     * context of the given package element.
      * Returns {@code null} if no doc comment was found.
-     * Future releases may support additional file types.
      *
-     * @param fileObject the content container
-     * @return a doc tree path containing the doc comment read from the given file.
+     * @param fileObject a file object encapsulating the HTML content
+     * @param packageElement a package element to associate with the given file object
+     * representing a legacy package.html, null otherwise
+     * @return a doc tree path containing the doc comment parsed from the given file
+     * @throws IllegalArgumentException if the fileObject is not an HTML file
      *
      * @since 9
      */
-    public abstract DocTreePath getDocTreePath(FileObject fileObject);
+    public abstract DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement);
 
     /**
      * Returns the language model element referred to by the leaf node of the given
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java	Fri Jan 20 19:10:00 2017 +0000
@@ -423,7 +423,16 @@
                 break;
 
             case OTHER:
-                env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
+                switch (t) {
+                    case SCRIPT:
+                        // <script> may or may not be allowed, depending on --allow-script-in-comments
+                        // but we allow it here, and rely on a separate scanner to detect all uses
+                        // of JavaScript, including <script> tags, and use in attributes, etc.
+                        break;
+
+                    default:
+                        env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
+                }
                 return;
         }
 
@@ -552,15 +561,19 @@
                 if (!first)
                     env.messages.error(HTML, tree, "dc.attr.repeated", name);
             }
-            AttrKind k = currTag.getAttrKind(name);
-            switch (env.htmlVersion) {
-                case HTML4:
-                    validateHtml4Attrs(tree, name, k);
-                    break;
+            // for now, doclint allows all attribute names beginning with "on" as event handler names,
+            // without checking the validity or applicability of the name
+            if (!name.toString().startsWith("on")) {
+                AttrKind k = currTag.getAttrKind(name);
+                switch (env.htmlVersion) {
+                    case HTML4:
+                        validateHtml4Attrs(tree, name, k);
+                        break;
 
-                case HTML5:
-                    validateHtml5Attrs(tree, name, k);
-                    break;
+                    case HTML5:
+                        validateHtml5Attrs(tree, name, k);
+                        break;
+                }
             }
 
             if (attr != null) {
@@ -722,6 +735,9 @@
     }
 
     private void checkURI(AttributeTree tree, String uri) {
+        // allow URIs beginning with javascript:, which would otherwise be rejected by the URI API.
+        if (uri.startsWith("javascript:"))
+            return;
         try {
             URI u = new URI(uri);
         } catch (URISyntaxException e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -287,7 +287,8 @@
     SAMP(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
 
-    SCRIPT(BlockType.OTHER, EndKind.REQUIRED),
+    SCRIPT(BlockType.OTHER, EndKind.REQUIRED,
+            attrs(AttrKind.ALL, SRC)),
 
     SECTION(HtmlVersion.HTML5, BlockType.BLOCK, EndKind.REQUIRED,
             EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java	Fri Jan 20 19:10:00 2017 +0000
@@ -174,7 +174,6 @@
     private JavaFileManager fileManager;
     private ParserFactory parser;
     private Symtab syms;
-    private Map<JavaFileObject, PackageSymbol> javaFileObjectToPackageMap;
 
     // called reflectively from Trees.instance(CompilationTask task)
     public static JavacTrees instance(JavaCompiler.CompilationTask task) {
@@ -198,7 +197,6 @@
     }
 
     protected JavacTrees(Context context) {
-        javaFileObjectToPackageMap = new HashMap<>();
         this.breakIterator = null;
         context.put(JavacTrees.class, this);
         init(context);
@@ -1039,10 +1037,11 @@
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
-    public DocTreePath getDocTreePath(FileObject fileObject) {
+    public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) {
         JavaFileObject jfo = asJavaFileObject(fileObject);
         DocCommentTree docCommentTree = getDocCommentTree(jfo);
-        return new DocTreePath(makeTreePath(jfo, docCommentTree), docCommentTree);
+        TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree);
+        return new DocTreePath(treePath, docCommentTree);
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
@@ -1160,17 +1159,8 @@
         }
     }
 
-    /**
-     * Register a file object, such as for a package.html, that provides
-     * doc comments for a package.
-     * @param psym the PackageSymbol representing the package.
-     * @param jfo  the JavaFileObject for the given package.
-     */
-    public void putJavaFileObject(PackageSymbol psym, JavaFileObject jfo) {
-        javaFileObjectToPackageMap.putIfAbsent(jfo, psym);
-    }
-
-    private TreePath makeTreePath(final JavaFileObject jfo, DocCommentTree dcTree) {
+    private TreePath makeTreePath(final PackageSymbol psym, final JavaFileObject jfo,
+            DocCommentTree dcTree) {
         JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
             public int getPos() {
                 return Position.FIRSTPOS;
@@ -1191,9 +1181,6 @@
             }
         };
 
-        PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo,
-                syms.unnamedModule.unnamedPackage);
-
         jcCompilationUnit.docComments = new DocCommentTable() {
             @Override
             public boolean hasComment(JCTree tree) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -1045,7 +1045,7 @@
         DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
         WARN_DEPRECATED(0x0002),
         WARN_DEPRECATED_REMOVAL(0x0004),
-        WARN_INCUBATOR(0x0008);
+        WARN_INCUBATING(0x0008);
 
         public static int value(Set<ModuleResolutionFlags> s) {
             int v = 0;
@@ -1070,6 +1070,8 @@
         public Name fullname;
         public ClassSymbol package_info; // see bug 6443073
         public ModuleSymbol modle;
+        // the file containing the documentation comments for the package
+        public JavaFileObject sourcefile;
 
         public PackageSymbol(Name name, Type type, Symbol owner) {
             super(PCK, 0, name, type, owner);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -818,4 +818,12 @@
     public Collection<ModuleSymbol> getAllModules() {
         return modules.values();
     }
+
+    public Iterable<ClassSymbol> getClassesForName(Name candidate) {
+        return classes.getOrDefault(candidate, Collections.emptyMap()).values();
+    }
+
+    public Iterable<PackageSymbol> getPackagesForName(Name candidate) {
+        return packages.getOrDefault(candidate, Collections.emptyMap()).values();
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java	Fri Jan 20 19:10:00 2017 +0000
@@ -118,6 +118,8 @@
         Source source = Source.instance(context);
         allowRepeatedAnnos = source.allowRepeatedAnnotations();
         sourceName = source.name;
+
+        blockCount = 1;
     }
 
     /** Semaphore to delay annotation processing */
@@ -144,6 +146,10 @@
     /** are we blocking annotation processing? */
     public boolean annotationsBlocked() {return blockCount > 0; }
 
+    public void enterDone() {
+        unblockAnnotations();
+    }
+
     public List<TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
         if (annotations.isEmpty()) {
             return List.nil();
@@ -1316,4 +1322,8 @@
                     }
                 };
     }
+
+    public void newRound() {
+        blockCount = 1;
+    }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -41,6 +41,7 @@
 import java.util.function.Predicate;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import javax.lang.model.SourceVersion;
@@ -114,6 +115,7 @@
 import static com.sun.tools.javac.code.Kinds.Kind.ERR;
 import static com.sun.tools.javac.code.Kinds.Kind.MDL;
 import static com.sun.tools.javac.code.Kinds.Kind.MTH;
+import com.sun.tools.javac.code.Symbol.ModuleResolutionFlags;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 
 /**
@@ -374,6 +376,9 @@
                                 log.error(decl.qualId, Errors.ModuleNameMismatch(msym.name, name));
                             }
                         } else {
+                            if (tree.getPackage() == null) {
+                                log.error(tree.pos(), Errors.UnnamedPkgNotAllowedNamedModules);
+                            }
                             msym = syms.enterModule(name);
                         }
                         if (msym.sourceLocation == null) {
@@ -388,7 +393,11 @@
                     } else if (c != null && c.packge().modle == syms.unnamedModule) {
                         tree.modle = syms.unnamedModule;
                     } else {
-                        log.error(tree.pos(), Errors.UnnamedPkgNotAllowedNamedModules);
+                        if (tree.getModuleDecl() != null) {
+                            log.error(tree.pos(), Errors.ModuleNotFoundOnModuleSourcePath);
+                        } else {
+                            log.error(tree.pos(), Errors.NotInModuleOnModuleSourcePath);
+                        }
                         tree.modle = syms.errModule;
                     }
                 } catch (IOException e) {
@@ -457,19 +466,27 @@
         }
     }
 
+    /**
+     * Determine the location for the module on the module source path
+     * or source output directory which contains a given CompilationUnit.
+     * If the source output directory is unset, the class output directory
+     * will be checked instead.
+     * {@code null} is returned if no such module can be found.
+     * @param tree the compilation unit tree
+     * @return the location for the enclosing module
+     * @throws IOException if there is a problem while searching for the module.
+     */
     private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
+        Name pkgName;
         if (tree.getModuleDecl() != null) {
-            return getModuleLocation(tree.sourcefile, null);
-        } else if (tree.getPackage() != null) {
-            JCPackageDecl pkg = tree.getPackage();
-            return getModuleLocation(tree.sourcefile, TreeInfo.fullName(pkg.pid));
+            pkgName = null;
         } else {
-            // code in unnamed module
-            return null;
+            JCPackageDecl pkg = tree.getPackage();
+            pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid);
         }
-    }
 
-    private Location getModuleLocation(JavaFileObject fo, Name pkgName) throws IOException {
+        JavaFileObject fo = tree.sourcefile;
+
         // For now, just check module source path.
         // We may want to check source path as well.
         Location loc =
@@ -482,7 +499,6 @@
                 fileManager.getLocationForModule(sourceOutput,
                                                  fo, (pkgName == null) ? null : pkgName.toString());
         }
-
         return loc;
     }
 
@@ -962,7 +978,7 @@
 
         @Override
         public void visitRequires(JCRequires tree) {
-            if (tree.directive != null) {
+            if (tree.directive != null && allModules().contains(tree.directive.module)) {
                 chk.checkDeprecated(tree.moduleName.pos(), msym, tree.directive.module);
                 msym.directives = msym.directives.prepend(tree.directive);
             }
@@ -1076,6 +1092,10 @@
         Predicate<ModuleSymbol> observablePred = sym ->
              (observable == null) ? (moduleFinder.findModule(sym).kind != ERR) : observable.contains(sym);
         Predicate<ModuleSymbol> systemModulePred = sym -> (sym.flags() & Flags.SYSTEM_MODULE) != 0;
+        Predicate<ModuleSymbol> noIncubatorPred = sym -> {
+            sym.complete();
+            return !sym.resolutionFlags.contains(ModuleResolutionFlags.DO_NOT_RESOLVE_BY_DEFAULT);
+        };
         Set<ModuleSymbol> enabledRoot = new LinkedHashSet<>();
 
         if (rootModules.contains(syms.unnamedModule)) {
@@ -1094,7 +1114,7 @@
             }
 
             for (ModuleSymbol sym : new HashSet<>(syms.getAllModules())) {
-                if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym)) {
+                if (systemModulePred.test(sym) && observablePred.test(sym) && jdkModulePred.test(sym) && noIncubatorPred.test(sym)) {
                     enabledRoot.add(sym);
                 }
             }
@@ -1114,14 +1134,14 @@
                 Stream<ModuleSymbol> modules;
                 switch (added) {
                     case ALL_SYSTEM:
-                        modules = syms.getAllModules()
-                                      .stream()
-                                      .filter(systemModulePred.and(observablePred));
+                        modules = new HashSet<>(syms.getAllModules())
+                                .stream()
+                                .filter(systemModulePred.and(observablePred).and(noIncubatorPred));
                         break;
                     case ALL_MODULE_PATH:
-                        modules = syms.getAllModules()
-                                      .stream()
-                                      .filter(systemModulePred.negate().and(observablePred));
+                        modules = new HashSet<>(syms.getAllModules())
+                                .stream()
+                                .filter(systemModulePred.negate().and(observablePred));
                         break;
                     default:
                         if (!isValidName(added))
@@ -1141,6 +1161,15 @@
 
         result.add(syms.unnamedModule);
 
+        String incubatingModules = result.stream()
+                .filter(msym -> msym.resolutionFlags.contains(ModuleResolutionFlags.WARN_INCUBATING))
+                .map(msym -> msym.name.toString())
+                .collect(Collectors.joining(","));
+
+        if (!incubatingModules.isEmpty()) {
+            log.warning(Warnings.IncubatingModules(incubatingModules));
+        }
+
         allModules = result;
 
         //add module versions from options, if any:
@@ -1234,7 +1263,6 @@
         msym.requires = msym.requires.appendList(List.from(addReads.getOrDefault(msym, Collections.emptySet())));
 
         List<RequiresDirective> requires = msym.requires;
-        List<RequiresDirective> previous = null;
 
         while (requires.nonEmpty()) {
             if (!allModules().contains(requires.head.module)) {
@@ -1249,13 +1277,7 @@
                 } else {
                     Assert.check((msym.flags() & Flags.AUTOMATIC_MODULE) == 0);
                 }
-                if (previous != null) {
-                    previous.tail = requires.tail;
-                } else {
-                    msym.requires.tail = requires.tail;
-                }
-            } else {
-                previous = requires;
+                msym.requires = List.filter(msym.requires, requires.head);
             }
             requires = requires.tail;
         }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -41,6 +41,7 @@
 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.resources.CompilerProperties.Fragments;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
@@ -61,12 +62,12 @@
 import java.util.Set;
 import java.util.function.BiFunction;
 import java.util.function.BiPredicate;
+import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
 import javax.lang.model.element.ElementVisitor;
 
-import com.sun.tools.javac.code.Directive.ExportsDirective;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Flags.STATIC;
@@ -74,9 +75,8 @@
 import static com.sun.tools.javac.code.Kinds.Kind.*;
 import static com.sun.tools.javac.code.TypeTag.*;
 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
-import com.sun.tools.javac.resources.CompilerProperties.Errors;
-import com.sun.tools.javac.resources.CompilerProperties.Fragments;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
+import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
 
 /** Helper class for name resolution, used mostly by the attribution phase.
  *
@@ -1970,7 +1970,7 @@
      *  @param env       The current environment.
      *  @param name      The fully qualified name of the class to be loaded.
      */
-    Symbol loadClass(Env<AttrContext> env, Name name) {
+    Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) {
         try {
             ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
             return isAccessible(env, c) ? c : new AccessError(env, null, c);
@@ -1987,40 +1987,60 @@
         }
     }
 
-    public static interface RecoveryLoadClass {
+    public interface RecoveryLoadClass {
         Symbol loadClass(Env<AttrContext> env, Name name);
     }
 
-    private RecoveryLoadClass recoveryLoadClass = new RecoveryLoadClass() {
-        @Override
-        public Symbol loadClass(Env<AttrContext> env, Name name) {
-            if (allowModules) {
-                Scope importScope = env.toplevel.namedImportScope;
-                Symbol existing = importScope.findFirst(Convert.shortName(name),
-                                                        sym -> sym.kind == TYP && sym.flatName() == name);
-
-                if (existing != null) {
-                    return new InvisibleSymbolError(env, true, existing);
-                }
-
-                return lookupInvisibleSymbol(env, name, syms::getClass, (ms, n) -> {
+    private final RecoveryLoadClass noRecovery = (env, name) -> null;
+
+    private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() {
+        @Override public Symbol loadClass(Env<AttrContext> env, Name name) {
+            List<Name> candidates = Convert.classCandidates(name);
+            return lookupInvisibleSymbol(env, name,
+                                         n -> () -> createCompoundIterator(candidates,
+                                                                           c -> syms.getClassesForName(c)
+                                                                                    .iterator()),
+                                         (ms, n) -> {
+                for (Name candidate : candidates) {
                     try {
-                        return finder.loadClass(ms, n);
+                        return finder.loadClass(ms, candidate);
                     } catch (CompletionFailure cf) {
                         //ignore
-                        return null;
                     }
-                }, sym -> sym.kind == Kind.TYP, false, typeNotFound);
-            }
-            return null;
+                }
+                return null;
+            }, sym -> sym.kind == Kind.TYP, false, typeNotFound);
         }
     };
 
-    public RecoveryLoadClass setRecoveryLoadClass(RecoveryLoadClass recovery) {
-        RecoveryLoadClass prev = recoveryLoadClass;
-        recoveryLoadClass = recovery;
-        return prev;
-    }
+    private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> {
+        Scope importScope = env.toplevel.namedImportScope;
+        Symbol existing = importScope.findFirst(Convert.shortName(name),
+                                                sym -> sym.kind == TYP && sym.flatName() == name);
+
+        if (existing != null) {
+            return new InvisibleSymbolError(env, true, existing);
+        }
+        return null;
+    };
+
+    private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> {
+        Scope importScope = env.toplevel.starImportScope;
+        Symbol existing = importScope.findFirst(Convert.shortName(name),
+                                                sym -> sym.kind == TYP && sym.flatName() == name);
+
+        if (existing != null) {
+            try {
+                existing = finder.loadClass(existing.packge().modle, name);
+
+                return new InvisibleSymbolError(env, true, existing);
+            } catch (CompletionFailure cf) {
+                //ignore
+            }
+        }
+
+        return null;
+    };
 
     Symbol lookupPackage(Env<AttrContext> env, Name name) {
         PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
@@ -2034,7 +2054,7 @@
                                                           .stream()
                                                           .anyMatch(p -> p.fullname.startsWith(nameAndDot));
 
-                return lookupInvisibleSymbol(env, name, syms::getPackage, syms::enterPackage, sym -> {
+                return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
                     sym.complete();
                     return sym.exists();
                 }, prefixOfKnown, pack);
@@ -2059,42 +2079,44 @@
         return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
     }
 
-    private Symbol lookupInvisibleSymbol(Env<AttrContext> env,
-                                         Name name,
-                                         BiFunction<ModuleSymbol, Name, Symbol> get,
-                                         BiFunction<ModuleSymbol, Name, Symbol> load,
-                                         Predicate<Symbol> validate,
-                                         boolean suppressError,
-                                         Symbol defaultResult) {
+    private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env,
+                                                            Name name,
+                                                            Function<Name, Iterable<S>> get,
+                                                            BiFunction<ModuleSymbol, Name, S> load,
+                                                            Predicate<S> validate,
+                                                            boolean suppressError,
+                                                            Symbol defaultResult) {
         //even if a class/package cannot be found in the current module and among packages in modules
         //it depends on that are exported for any or this module, the class/package may exist internally
         //in some of these modules, or may exist in a module on which this module does not depend.
         //Provide better diagnostic in such cases by looking for the class in any module:
+        Iterable<? extends S> candidates = get.apply(name);
+
+        for (S sym : candidates) {
+            if (validate.test(sym))
+                return new InvisibleSymbolError(env, suppressError, sym);
+        }
+
         Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
 
         recoverableModules.remove(env.toplevel.modle);
 
         for (ModuleSymbol ms : recoverableModules) {
-            Symbol sym = get.apply(ms, name);
-
             //avoid overly eager completing classes from source-based modules, as those
             //may not be completable with the current compiler settings:
-            if (sym == null && (ms.sourceLocation == null)) {
+            if (ms.sourceLocation == null) {
                 if (ms.classLocation == null) {
                     ms = moduleFinder.findModule(ms);
                 }
 
                 if (ms.kind != ERR) {
-                    sym = load.apply(ms, name);
+                    S sym = load.apply(ms, name);
+
+                    if (sym != null && validate.test(sym)) {
+                        return new InvisibleSymbolError(env, suppressError, sym);
+                    }
                 }
             }
-
-            if (sym == null)
-                continue;
-
-            if (validate.test(sym)) {
-                return new InvisibleSymbolError(env, suppressError, sym);
-            }
         }
 
         return defaultResult;
@@ -2186,10 +2208,10 @@
      *  @param scope     The scope in which to look for the type.
      *  @param name      The type's name.
      */
-    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
+    Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
         Symbol bestSoFar = typeNotFound;
         for (Symbol s : scope.getSymbolsByName(name)) {
-            Symbol sym = loadClass(env, s.flatName());
+            Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
             if (bestSoFar.kind == TYP && sym.kind == TYP &&
                 bestSoFar != sym)
                 return new AmbiguityError(bestSoFar, sym);
@@ -2260,15 +2282,15 @@
         }
 
         if (!env.tree.hasTag(IMPORT)) {
-            sym = findGlobalType(env, env.toplevel.namedImportScope, name);
+            sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery);
             if (sym.exists()) return sym;
             else bestSoFar = bestOf(bestSoFar, sym);
 
-            sym = findGlobalType(env, env.toplevel.packge.members(), name);
+            sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery);
             if (sym.exists()) return sym;
             else bestSoFar = bestOf(bestSoFar, sym);
 
-            sym = findGlobalType(env, env.toplevel.starImportScope, name);
+            sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
             if (sym.exists()) return sym;
             else bestSoFar = bestOf(bestSoFar, sym);
         }
@@ -2315,7 +2337,11 @@
         Name fullname = TypeSymbol.formFullName(name, pck);
         Symbol bestSoFar = typeNotFound;
         if (kind.contains(KindSelector.TYP)) {
-            Symbol sym = loadClass(env, fullname);
+            RecoveryLoadClass recoveryLoadClass =
+                    allowModules && !kind.contains(KindSelector.PCK) &&
+                    !pck.exists() && !env.info.isSpeculative ?
+                        doRecoveryLoadClass : noRecovery;
+            Symbol sym = loadClass(env, fullname, recoveryLoadClass);
             if (sym.exists()) {
                 // don't allow programs to use flatnames
                 if (name == sym.name) return sym;
@@ -4136,11 +4162,21 @@
 
             JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
 
-            if (pos.getTree() != null && pos.getTree().hasTag(SELECT) && sym.owner.kind == PCK) {
-                pos = ((JCFieldAccess) pos.getTree()).selected.pos();
-
-                return diags.create(dkind, log.currentSource(),
-                        pos, "package.not.visible", sym.packge(), details);
+            if (pos.getTree() != null) {
+                Symbol o = sym;
+                JCTree tree = pos.getTree();
+
+                while (o.kind != PCK && tree.hasTag(SELECT)) {
+                    o = o.owner;
+                    tree = ((JCFieldAccess) tree).selected;
+                }
+
+                if (o.kind == PCK) {
+                    pos = tree.pos();
+
+                    return diags.create(dkind, log.currentSource(),
+                            pos, "package.not.visible", o, details);
+                }
             }
 
             return diags.create(dkind, log.currentSource(),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -553,7 +553,7 @@
 
         @Override
         Location getLocationForModule(Path dir) {
-            return pathLocations.get(dir);
+            return (pathLocations == null) ? null : pathLocations.get(dir);
         }
 
         private boolean listed;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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,6 +29,7 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.CharBuffer;
+import java.nio.file.ClosedFileSystemException;
 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -2756,8 +2757,8 @@
                     currentModule.provides = List.nil();
                 }
             }
-        } catch (IOException ex) {
-            throw badClassFile("unable.to.access.file", ex.getMessage());
+        } catch (IOException | ClosedFileSystemException ex) {
+            throw badClassFile("unable.to.access.file", ex.toString());
         } catch (ArrayIndexOutOfBoundsException ex) {
             throw badClassFile("bad.class.file", c.flatname);
         } finally {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java	Fri Jan 20 19:10:00 2017 +0000
@@ -588,7 +588,9 @@
         checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0,
                 option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name),
                 Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH,
-                Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES, Option.LIMIT_MODULES,
+                Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES,
+                Option.ADD_EXPORTS, Option.ADD_OPENS, Option.ADD_READS,
+                Option.LIMIT_MODULES,
                 Option.PATCH_MODULE);
 
         if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -363,7 +363,7 @@
      **/
     protected boolean implicitSourceFilesRead;
 
-    protected boolean enterDone;
+    private boolean enterDone;
 
     protected CompileStates compileStates;
 
@@ -1042,7 +1042,7 @@
     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
         modules.initModules(roots);
         if (roots.isEmpty()) {
-            enterDone = true;
+            enterDone();
         }
         return roots;
     }
@@ -1063,7 +1063,7 @@
 
         enter.main(roots);
 
-        enterDone = true;
+        enterDone();
 
         if (!taskListener.isEmpty()) {
             for (JCCompilationUnit unit: roots) {
@@ -1725,6 +1725,11 @@
         }
     }
 
+    public void enterDone() {
+        enterDone = true;
+        annotate.enterDone();
+    }
+
     public boolean isEnterDone() {
         return enterDone;
     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Fri Jan 20 19:10:00 2017 +0000
@@ -184,39 +184,34 @@
             return nameToSymbol(syms.noModule, nameStr, clazz);
         }
 
-        RecoveryLoadClass prevRecoveryLoadClass = resolve.setRecoveryLoadClass((env, name) -> null);
-        try {
-            Set<S> found = new LinkedHashSet<>();
+        Set<S> found = new LinkedHashSet<>();
+
+        for (ModuleSymbol msym : modules.allModules()) {
+            S sym = nameToSymbol(msym, nameStr, clazz);
 
-            for (ModuleSymbol msym : modules.allModules()) {
-                S sym = nameToSymbol(msym, nameStr, clazz);
-
-                if (sym != null) {
-                    if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
-                        //do not add packages without members:
-                        found.add(sym);
-                    }
+            if (sym != null) {
+                if (!allowModules || clazz == ClassSymbol.class || !sym.members().isEmpty()) {
+                    //do not add packages without members:
+                    found.add(sym);
                 }
             }
+        }
 
-            if (found.size() == 1) {
-                return found.iterator().next();
-            } else if (found.size() > 1) {
-                //more than one element found, produce a note:
-                if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
-                    String moduleNames = found.stream()
-                                              .map(s -> s.packge().modle)
-                                              .map(m -> m.toString())
-                                              .collect(Collectors.joining(", "));
-                    log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
-                }
-                return null;
-            } else {
-                //not found, or more than one element found:
-                return null;
+        if (found.size() == 1) {
+            return found.iterator().next();
+        } else if (found.size() > 1) {
+            //more than one element found, produce a note:
+            if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
+                String moduleNames = found.stream()
+                                          .map(s -> s.packge().modle)
+                                          .map(m -> m.toString())
+                                          .collect(Collectors.joining(", "));
+                log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
             }
-        } finally {
-            resolve.setRecoveryLoadClass(prevRecoveryLoadClass);
+            return null;
+        } else {
+            //not found, or more than one element found:
+            return null;
         }
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Fri Jan 20 19:10:00 2017 +0000
@@ -30,7 +30,6 @@
 import java.util.Map;
 
 import com.sun.source.doctree.AttributeTree.ValueKind;
-import com.sun.source.doctree.DocTree;
 import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
 import com.sun.tools.javac.parser.Tokens.Comment;
 import com.sun.tools.javac.parser.Tokens.TokenKind;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jan 20 19:10:00 2017 +0000
@@ -588,7 +588,7 @@
     /**
      * Ident = IDENTIFIER
      */
-    protected Name ident() {
+    public Name ident() {
         return ident(false);
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -92,6 +92,7 @@
 
 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
 import static com.sun.tools.javac.code.Kinds.Kind.*;
+import com.sun.tools.javac.comp.Annotate;
 import static com.sun.tools.javac.comp.CompileStates.CompileState;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 
@@ -123,6 +124,7 @@
     private final JavaCompiler compiler;
     private final Modules modules;
     private final Types types;
+    private final Annotate annotate;
 
     /**
      * Holds relevant state history of which processors have been
@@ -219,6 +221,7 @@
         typeUtils = JavacTypes.instance(context);
         modules = Modules.instance(context);
         types = Types.instance(context);
+        annotate = Annotate.instance(context);
         processorOptions = initProcessorOptions();
         unmatchedProcessorOptions = initUnmatchedProcessorOptions();
         messages = JavacMessages.instance(context);
@@ -1256,6 +1259,7 @@
             compiler.newRound();
             modules.newRound();
             types.newRound();
+            annotate.newRound();
 
             boolean foundError = false;
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jan 20 19:10:00 2017 +0000
@@ -1535,6 +1535,10 @@
 compiler.warn.poor.choice.for.module.name=\
     module name {0} should avoid terminal digits
 
+# 0: string
+compiler.warn.incubating.modules=\
+    using incubating module(s): {0}
+
 # 0: symbol, 1: symbol
 compiler.warn.has.been.deprecated=\
     {0} in {1} has been deprecated
@@ -2845,6 +2849,12 @@
 compiler.err.too.many.modules=\
     too many module declarations found
 
+compiler.err.module.not.found.on.module.source.path=\
+    module not found on module source path
+
+compiler.err.not.in.module.on.module.source.path=\
+    not in a module on the module source path
+
 # 0: symbol
 compiler.err.duplicate.module=\
     duplicate module: {0}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Convert.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -335,4 +335,16 @@
         }
         return names;
     }
+
+    public static List<Name> classCandidates(Name name) {
+        List<Name> names = List.nil();
+        String nameStr = name.toString();
+        int index = -1;
+        while ((index = nameStr.indexOf('.', index + 1)) > 0) {
+            String pack = nameStr.substring(0, index + 1);
+            String clz = nameStr.substring(index + 1).replace('.', '$');
+            names = names.prepend(name.table.names.fromString(pack + clz));
+        }
+        return names.reverse();
+    }
 }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Fri Jan 20 19:10:00 2017 +0000
@@ -40,6 +40,7 @@
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.StringUtils;
+import com.sun.tools.javadoc.main.JavaScriptScanner;
 import com.sun.tools.javadoc.main.RootDocImpl;
 
 /**
@@ -189,6 +190,11 @@
     public Set<String> doclintOpts = new LinkedHashSet<>();
 
     /**
+     * Whether or not to check for JavaScript in doc comments.
+     */
+    private boolean allowScriptInComments;
+
+    /**
      * Unique Resource Handler for this package.
      */
     public final MessageRetriever standardmessage;
@@ -309,8 +315,11 @@
                 doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + opt.substring(opt.indexOf(":") + 1));
             } else if (opt.startsWith("-xdoclint/package:")) {
                 doclintOpts.add(DocLint.XCHECK_PACKAGE + opt.substring(opt.indexOf(":") + 1));
+            } else if (opt.equals("--allow-script-in-comments")) {
+                allowScriptInComments = true;
             }
         }
+
         if (root.specifiedClasses().length > 0) {
             Map<String,PackageDoc> map = new HashMap<>();
             PackageDoc pd;
@@ -322,15 +331,37 @@
                 }
             }
         }
+
         setCreateOverview();
         setTopFile(root);
 
         if (root instanceof RootDocImpl) {
             ((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames(),
                     StringUtils.toLowerCase(htmlVersion.name()));
+            JavaScriptScanner jss = ((RootDocImpl) root).initJavaScriptScanner(isAllowScriptInComments());
+            if (jss != null) {
+                // In a more object-oriented world, this would be done by methods on the Option objects.
+                // Note that -windowtitle silently removes any and all HTML elements, and so does not need
+                // to be handled here.
+                checkJavaScript(jss, "-header", header);
+                checkJavaScript(jss, "-footer", footer);
+                checkJavaScript(jss, "-top", top);
+                checkJavaScript(jss, "-bottom", bottom);
+                checkJavaScript(jss, "-doctitle", doctitle);
+                checkJavaScript(jss, "-packagesheader", packagesheader);
+            }
         }
     }
 
+    private void checkJavaScript(JavaScriptScanner jss, final String opt, String value) {
+        jss.parse(value, new JavaScriptScanner.Reporter() {
+            public void report() {
+                root.printError(getText("doclet.JavaScript_in_option", opt));
+                throw new FatalError();
+            }
+        });
+    }
+
     /**
      * Returns the "length" of a given option. If an option takes no
      * arguments, its length is one. If it takes one argument, it's
@@ -366,7 +397,8 @@
             option.equals("-html5") ||
             option.equals("-xdoclint") ||
             option.startsWith("-xdoclint:") ||
-            option.startsWith("-xdoclint/package:")) {
+            option.startsWith("-xdoclint/package:") ||
+            option.startsWith("--allow-script-in-comments")) {
             return 1;
         } else if (option.equals("-help")) {
             // Uugh: first, this should not be hidden inside optionLength,
@@ -666,4 +698,13 @@
         }
         tagSearchIndexKeys = tagSearchIndexMap.keySet();
     }
+
+    /**
+     * Returns whether or not to allow JavaScript in comments.
+     * Default is off; can be set true from a command line option.
+     * @return the allowScriptInComments
+     */
+    public boolean isAllowScriptInComments() {
+        return allowScriptInComments;
+    }
 }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java	Fri Jan 20 19:10:00 2017 +0000
@@ -237,6 +237,8 @@
                 }
             } catch (IOException e) {
                 throw new DocletAbortException(e);
+            } catch (FatalError fe) {
+                throw fe;
             } catch (DocletAbortException de) {
                 de.printStackTrace();
                 throw de;
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java	Fri Jan 20 19:10:00 2017 +0000
@@ -148,7 +148,9 @@
 
     public final Content descfrmInterfaceLabel;
 
-    private final Writer writer;
+    private final DocFile file;
+
+    private Writer writer;
 
     protected Content script;
 
@@ -164,7 +166,7 @@
      */
     public HtmlWriter(Configuration configuration, DocPath path)
             throws IOException, UnsupportedEncodingException {
-        writer = DocFile.createFileForOutput(configuration, path).openWriter();
+        file = DocFile.createFileForOutput(configuration, path);
         this.configuration = configuration;
         this.memberDetailsListPrinted = false;
         packageTableHeader = new String[] {
@@ -214,6 +216,7 @@
     }
 
     public void write(Content c) throws IOException {
+        writer = file.openWriter();
         c.write(writer, true);
     }
 
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java	Fri Jan 20 19:10:00 2017 +0000
@@ -90,6 +90,8 @@
         } catch (Configuration.Fault f) {
             root.printError(f.getMessage());
             return false;
+        } catch (FatalError fe) {
+            return false;
         } catch (DocletAbortException e) {
             e.printStackTrace();
             Throwable cause = e.getCause();
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java	Fri Jan 20 19:10:00 2017 +0000
@@ -145,7 +145,14 @@
             configuration.root.printError("Unknown element: " + component);
             throw new DocletAbortException(e);
         } catch (InvocationTargetException e) {
-            throw new DocletAbortException(e.getCause());
+            Throwable cause = e.getCause();
+            if (cause instanceof FatalError) {
+                throw (FatalError) cause;
+            } else if (cause instanceof DocletAbortException) {
+                throw (DocletAbortException) cause;
+            } else {
+                throw new DocletAbortException(cause);
+            }
         } catch (Exception e) {
             e.printStackTrace();
             configuration.root.printError("Exception " +
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Fri Jan 20 19:10:00 2017 +0000
@@ -29,6 +29,8 @@
 doclet.Building_Tree=Building tree for all the packages and classes...
 doclet.Building_Index=Building index for all the packages and classes...
 doclet.Building_Index_For_All_Classes=Building index for all classes...
+doclet.JavaScript_in_option=Argument for {0} contains JavaScript.\n\
+Use --allow-script-in-comments to allow use of JavaScript.
 doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
 doclet.Packages=Packages
 doclet.Other_Packages=Other Packages
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/util/FatalError.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+/**
+ *  <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>
+ */
+@Deprecated
+public class FatalError extends Error {
+    private static final long serialVersionUID = -9131058909576418984L;
+
+    public FatalError() { }
+}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -97,7 +97,7 @@
     final Enter enter;
 
     /** The name table. */
-    private Names names;
+    private final Names names;
 
     /** The encoding name. */
     private String encoding;
@@ -120,6 +120,7 @@
     JavaFileManager fileManager;
     Context context;
     DocLint doclint;
+    JavaScriptScanner javaScriptScanner;
 
     WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
 
@@ -858,6 +859,15 @@
         doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
     }
 
+    JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
+        if (allowScriptInComments) {
+            javaScriptScanner = null;
+        } else {
+            javaScriptScanner = new JavaScriptScanner();
+        }
+        return javaScriptScanner;
+    }
+
     boolean showTagMessages() {
         return (doclint == null);
     }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -36,6 +36,8 @@
 
 import com.sun.javadoc.*;
 import com.sun.source.util.TreePath;
+import com.sun.tools.doclets.internal.toolkit.util.DocletAbortException;
+import com.sun.tools.doclets.internal.toolkit.util.FatalError;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.util.Position;
@@ -128,6 +130,15 @@
     Comment comment() {
         if (comment == null) {
             String d = documentation();
+            if (env.javaScriptScanner != null) {
+                env.javaScriptScanner.parse(d, new JavaScriptScanner.Reporter() {
+                    @Override
+                    public void report() {
+                        env.error(DocImpl.this, "javadoc.JavaScript_in_comment");
+                        throw new FatalError();
+                    }
+                });
+            }
             if (env.doclint != null
                     && treePath != null
                     && env.shouldCheck(treePath.getCompilationUnit())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavaScriptScanner.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (c) 2012,2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javadoc.main;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.javadoc.main.JavaScriptScanner.TagParser.Kind;
+
+import static com.sun.tools.javac.util.LayoutCharacters.EOI;
+
+/**
+ * Parser to detect use of JavaScript in documentation comments.
+ */
+@Deprecated
+public class JavaScriptScanner {
+    public static interface Reporter {
+        void report();
+    }
+
+    static class ParseException extends Exception {
+        private static final long serialVersionUID = 0;
+        ParseException(String key) {
+            super(key);
+        }
+    }
+
+    private Reporter reporter;
+
+    /** The input buffer, index of most recent character read,
+     *  index of one past last character in buffer.
+     */
+    protected char[] buf;
+    protected int bp;
+    protected int buflen;
+
+    /** The current character.
+     */
+    protected char ch;
+
+    private boolean newline = true;
+
+    Map<String, TagParser> tagParsers;
+    Set<String> eventAttrs;
+    Set<String> uriAttrs;
+
+    public JavaScriptScanner() {
+        initTagParsers();
+        initEventAttrs();
+        initURIAttrs();
+    }
+
+    public void parse(String comment, Reporter r) {
+        reporter = r;
+        String c = comment;
+        buf = new char[c.length() + 1];
+        c.getChars(0, c.length(), buf, 0);
+        buf[buf.length - 1] = EOI;
+        buflen = buf.length - 1;
+        bp = -1;
+        newline = true;
+        nextChar();
+
+        blockContent();
+        blockTags();
+    }
+
+    private void checkHtmlTag(String tag) {
+        if (tag.equalsIgnoreCase("script")) {
+            reporter.report();
+        }
+    }
+
+    private void checkHtmlAttr(String name, String value) {
+        String n = name.toLowerCase(Locale.ENGLISH);
+        if (eventAttrs.contains(n)
+                || uriAttrs.contains(n)
+                    && value != null && value.toLowerCase(Locale.ENGLISH).trim().startsWith("javascript:")) {
+            reporter.report();
+        }
+    }
+
+    void nextChar() {
+        ch = buf[bp < buflen ? ++bp : buflen];
+        switch (ch) {
+            case '\f': case '\n': case '\r':
+                newline = true;
+        }
+    }
+
+    /**
+     * Read block content, consisting of text, html and inline tags.
+     * Terminated by the end of input, or the beginning of the next block tag:
+     * i.e. @ as the first non-whitespace character on a line.
+     */
+    @SuppressWarnings("fallthrough")
+    protected void blockContent() {
+
+        loop:
+        while (bp < buflen) {
+            switch (ch) {
+                case '\n': case '\r': case '\f':
+                    newline = true;
+                    // fallthrough
+
+                case ' ': case '\t':
+                    nextChar();
+                    break;
+
+                case '&':
+                    entity(null);
+                    break;
+
+                case '<':
+                    html();
+                    break;
+
+                case '>':
+                    newline = false;
+                    nextChar();
+                    break;
+
+                case '{':
+                    inlineTag(null);
+                    break;
+
+                case '@':
+                    if (newline) {
+                        break loop;
+                    }
+                    // fallthrough
+
+                default:
+                    newline = false;
+                    nextChar();
+            }
+        }
+    }
+
+    /**
+     * Read a series of block tags, including their content.
+     * Standard tags parse their content appropriately.
+     * Non-standard tags are represented by {@link UnknownBlockTag}.
+     */
+    protected void blockTags() {
+        while (ch == '@')
+            blockTag();
+    }
+
+    /**
+     * Read a single block tag, including its content.
+     * Standard tags parse their content appropriately.
+     * Non-standard tags are represented by {@link UnknownBlockTag}.
+     */
+    protected void blockTag() {
+        int p = bp;
+        try {
+            nextChar();
+            if (isIdentifierStart(ch)) {
+                String name = readTagName();
+                TagParser tp = tagParsers.get(name);
+                if (tp == null) {
+                    blockContent();
+                } else {
+                    switch (tp.getKind()) {
+                        case BLOCK:
+                            tp.parse(p);
+                            return;
+                        case INLINE:
+                            return;
+                    }
+                }
+            }
+            blockContent();
+        } catch (ParseException e) {
+            blockContent();
+        }
+    }
+
+    protected void inlineTag(Void list) {
+        newline = false;
+        nextChar();
+        if (ch == '@') {
+            inlineTag();
+        }
+    }
+
+    /**
+     * Read a single inline tag, including its content.
+     * Standard tags parse their content appropriately.
+     * Non-standard tags are represented by {@link UnknownBlockTag}.
+     * Malformed tags may be returned as {@link Erroneous}.
+     */
+    protected void inlineTag() {
+        int p = bp - 1;
+        try {
+            nextChar();
+            if (isIdentifierStart(ch)) {
+                String name = readTagName();
+                TagParser tp = tagParsers.get(name);
+
+                if (tp == null) {
+                    skipWhitespace();
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_ALL);
+                    nextChar();
+                } else {
+                    skipWhitespace();
+                    if (tp.getKind() == TagParser.Kind.INLINE) {
+                        tp.parse(p);
+                    } else { // handle block tags (ex: @see) in inline content
+                        inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip content
+                        nextChar();
+                    }
+                }
+            }
+        } catch (ParseException e) {
+        }
+    }
+
+    private static enum WhitespaceRetentionPolicy {
+        RETAIN_ALL,
+        REMOVE_FIRST_SPACE,
+        REMOVE_ALL
+    }
+
+    /**
+     * Read plain text content of an inline tag.
+     * Matching pairs of { } are skipped; the text is terminated by the first
+     * unmatched }. It is an error if the beginning of the next tag is detected.
+     */
+    private void inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException {
+        switch (whitespacePolicy) {
+            case REMOVE_ALL:
+                skipWhitespace();
+                break;
+            case REMOVE_FIRST_SPACE:
+                if (ch == ' ')
+                    nextChar();
+                break;
+            case RETAIN_ALL:
+            default:
+                // do nothing
+                break;
+
+        }
+        int pos = bp;
+        int depth = 1;
+
+        loop:
+        while (bp < buflen) {
+            switch (ch) {
+                case '\n': case '\r': case '\f':
+                    newline = true;
+                    break;
+
+                case ' ': case '\t':
+                    break;
+
+                case '{':
+                    newline = false;
+                    depth++;
+                    break;
+
+                case '}':
+                    if (--depth == 0) {
+                        return;
+                    }
+                    newline = false;
+                    break;
+
+                case '@':
+                    if (newline)
+                        break loop;
+                    newline = false;
+                    break;
+
+                default:
+                    newline = false;
+                    break;
+            }
+            nextChar();
+        }
+        throw new ParseException("dc.unterminated.inline.tag");
+    }
+
+    /**
+     * Read Java class name, possibly followed by member
+     * Matching pairs of {@literal < >} are skipped. The text is terminated by the first
+     * unmatched }. It is an error if the beginning of the next tag is detected.
+     */
+    // TODO: boolean allowMember should be enum FORBID, ALLOW, REQUIRE
+    // TODO: improve quality of parse to forbid bad constructions.
+    // TODO: update to use ReferenceParser
+    @SuppressWarnings("fallthrough")
+    protected void reference(boolean allowMember) throws ParseException {
+        int pos = bp;
+        int depth = 0;
+
+        // scan to find the end of the signature, by looking for the first
+        // whitespace not enclosed in () or <>, or the end of the tag
+        loop:
+        while (bp < buflen) {
+            switch (ch) {
+                case '\n': case '\r': case '\f':
+                    newline = true;
+                    // fallthrough
+
+                case ' ': case '\t':
+                    if (depth == 0)
+                        break loop;
+                    break;
+
+                case '(':
+                case '<':
+                    newline = false;
+                    depth++;
+                    break;
+
+                case ')':
+                case '>':
+                    newline = false;
+                    --depth;
+                    break;
+
+                case '}':
+                    if (bp == pos)
+                        return;
+                    newline = false;
+                    break loop;
+
+                case '@':
+                    if (newline)
+                        break loop;
+                    // fallthrough
+
+                default:
+                    newline = false;
+
+            }
+            nextChar();
+        }
+
+        if (depth != 0)
+            throw new ParseException("dc.unterminated.signature");
+    }
+
+    /**
+     * Read Java identifier
+     * Matching pairs of { } are skipped; the text is terminated by the first
+     * unmatched }. It is an error if the beginning of the next tag is detected.
+     */
+    @SuppressWarnings("fallthrough")
+    protected void identifier() throws ParseException {
+        skipWhitespace();
+        int pos = bp;
+
+        if (isJavaIdentifierStart(ch)) {
+            readJavaIdentifier();
+            return;
+        }
+
+        throw new ParseException("dc.identifier.expected");
+    }
+
+    /**
+     * Read a quoted string.
+     * It is an error if the beginning of the next tag is detected.
+     */
+    @SuppressWarnings("fallthrough")
+    protected void quotedString() {
+        int pos = bp;
+        nextChar();
+
+        loop:
+        while (bp < buflen) {
+            switch (ch) {
+                case '\n': case '\r': case '\f':
+                    newline = true;
+                    break;
+
+                case ' ': case '\t':
+                    break;
+
+                case '"':
+                    nextChar();
+                    // trim trailing white-space?
+                    return;
+
+                case '@':
+                    if (newline)
+                        break loop;
+
+            }
+            nextChar();
+        }
+    }
+
+    /**
+     * Read a term ie. one word.
+     * It is an error if the beginning of the next tag is detected.
+     */
+    @SuppressWarnings("fallthrough")
+    protected void inlineWord() {
+        int pos = bp;
+        int depth = 0;
+        loop:
+        while (bp < buflen) {
+            switch (ch) {
+                case '\n':
+                    newline = true;
+                    // fallthrough
+
+                case '\r': case '\f': case ' ': case '\t':
+                    return;
+
+                case '@':
+                    if (newline)
+                        break loop;
+
+                case '{':
+                    depth++;
+                    break;
+
+                case '}':
+                    if (depth == 0 || --depth == 0)
+                        return;
+                    break;
+            }
+            newline = false;
+            nextChar();
+        }
+    }
+
+    /**
+     * Read general text content of an inline tag, including HTML entities and elements.
+     * Matching pairs of { } are skipped; the text is terminated by the first
+     * unmatched }. It is an error if the beginning of the next tag is detected.
+     */
+    @SuppressWarnings("fallthrough")
+    private void inlineContent() {
+
+        skipWhitespace();
+        int pos = bp;
+        int depth = 1;
+
+        loop:
+        while (bp < buflen) {
+
+            switch (ch) {
+                case '\n': case '\r': case '\f':
+                    newline = true;
+                    // fall through
+
+                case ' ': case '\t':
+                    nextChar();
+                    break;
+
+                case '&':
+                    entity(null);
+                    break;
+
+                case '<':
+                    newline = false;
+                    html();
+                    break;
+
+                case '{':
+                    newline = false;
+                    depth++;
+                    nextChar();
+                    break;
+
+                case '}':
+                    newline = false;
+                    if (--depth == 0) {
+                        nextChar();
+                        return;
+                    }
+                    nextChar();
+                    break;
+
+                case '@':
+                    if (newline)
+                        break loop;
+                    // fallthrough
+
+                default:
+                    nextChar();
+                    break;
+            }
+        }
+
+    }
+
+    protected void entity(Void list) {
+        newline = false;
+        entity();
+    }
+
+    /**
+     * Read an HTML entity.
+     * {@literal &identifier; } or {@literal &#digits; } or {@literal &#xhex-digits; }
+     */
+    protected void entity() {
+        nextChar();
+        String name = null;
+        if (ch == '#') {
+            int namep = bp;
+            nextChar();
+            if (isDecimalDigit(ch)) {
+                nextChar();
+                while (isDecimalDigit(ch))
+                    nextChar();
+                name = new String(buf, namep, bp - namep);
+            } else if (ch == 'x' || ch == 'X') {
+                nextChar();
+                if (isHexDigit(ch)) {
+                    nextChar();
+                    while (isHexDigit(ch))
+                        nextChar();
+                    name = new String(buf, namep, bp - namep);
+                }
+            }
+        } else if (isIdentifierStart(ch)) {
+            name = readIdentifier();
+        }
+
+        if (name != null) {
+            if (ch != ';')
+                return;
+            nextChar();
+        }
+    }
+
+    /**
+     * Read the start or end of an HTML tag, or an HTML comment
+     * {@literal <identifier attrs> } or {@literal </identifier> }
+     */
+    protected void html() {
+        int p = bp;
+        nextChar();
+        if (isIdentifierStart(ch)) {
+            String name = readIdentifier();
+            checkHtmlTag(name);
+            htmlAttrs();
+            if (ch == '/') {
+                nextChar();
+            }
+            if (ch == '>') {
+                nextChar();
+                return;
+            }
+        } else if (ch == '/') {
+            nextChar();
+            if (isIdentifierStart(ch)) {
+                readIdentifier();
+                skipWhitespace();
+                if (ch == '>') {
+                    nextChar();
+                    return;
+                }
+            }
+        } else if (ch == '!') {
+            nextChar();
+            if (ch == '-') {
+                nextChar();
+                if (ch == '-') {
+                    nextChar();
+                    while (bp < buflen) {
+                        int dash = 0;
+                        while (ch == '-') {
+                            dash++;
+                            nextChar();
+                        }
+                        // Strictly speaking, a comment should not contain "--"
+                        // so dash > 2 is an error, dash == 2 implies ch == '>'
+                        // See http://www.w3.org/TR/html-markup/syntax.html#syntax-comments
+                        // for more details.
+                        if (dash >= 2 && ch == '>') {
+                            nextChar();
+                            return;
+                        }
+
+                        nextChar();
+                    }
+                }
+            }
+        }
+
+        bp = p + 1;
+        ch = buf[bp];
+    }
+
+    /**
+     * Read a series of HTML attributes, terminated by {@literal > }.
+     * Each attribute is of the form {@literal identifier[=value] }.
+     * "value" may be unquoted, single-quoted, or double-quoted.
+     */
+    protected void htmlAttrs() {
+        skipWhitespace();
+
+        loop:
+        while (isIdentifierStart(ch)) {
+            int namePos = bp;
+            String name = readAttributeName();
+            skipWhitespace();
+            StringBuilder value = new StringBuilder();
+            if (ch == '=') {
+                nextChar();
+                skipWhitespace();
+                if (ch == '\'' || ch == '"') {
+                    char quote = ch;
+                    nextChar();
+                    while (bp < buflen && ch != quote) {
+                        if (newline && ch == '@') {
+                            // No point trying to read more.
+                            // In fact, all attrs get discarded by the caller
+                            // and superseded by a malformed.html node because
+                            // the html tag itself is not terminated correctly.
+                            break loop;
+                        }
+                        value.append(ch);
+                        nextChar();
+                    }
+                    nextChar();
+                } else {
+                    while (bp < buflen && !isUnquotedAttrValueTerminator(ch)) {
+                        value.append(ch);
+                        nextChar();
+                    }
+                }
+                skipWhitespace();
+            }
+            checkHtmlAttr(name, value.toString());
+        }
+    }
+
+    protected void attrValueChar(Void list) {
+        switch (ch) {
+            case '&':
+                entity(list);
+                break;
+
+            case '{':
+                inlineTag(list);
+                break;
+
+            default:
+                nextChar();
+        }
+    }
+
+    protected boolean isIdentifierStart(char ch) {
+        return Character.isUnicodeIdentifierStart(ch);
+    }
+
+    protected String readIdentifier() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && Character.isUnicodeIdentifierPart(ch))
+            nextChar();
+        return new String(buf, start, bp - start);
+    }
+
+    protected String readAttributeName() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && (Character.isUnicodeIdentifierPart(ch) || ch == '-'))
+            nextChar();
+        return new String(buf, start, bp - start);
+    }
+
+    protected String readTagName() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen
+                && (Character.isUnicodeIdentifierPart(ch) || ch == '.'
+                || ch == '-' || ch == ':')) {
+            nextChar();
+        }
+        return new String(buf, start, bp - start);
+    }
+
+    protected boolean isJavaIdentifierStart(char ch) {
+        return Character.isJavaIdentifierStart(ch);
+    }
+
+    protected String readJavaIdentifier() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && Character.isJavaIdentifierPart(ch))
+            nextChar();
+        return new String(buf, start, bp - start);
+    }
+
+    protected boolean isDecimalDigit(char ch) {
+        return ('0' <= ch && ch <= '9');
+    }
+
+    protected boolean isHexDigit(char ch) {
+        return ('0' <= ch && ch <= '9')
+                || ('a' <= ch && ch <= 'f')
+                || ('A' <= ch && ch <= 'F');
+    }
+
+    protected boolean isUnquotedAttrValueTerminator(char ch) {
+        switch (ch) {
+            case '\f': case '\n': case '\r': case '\t':
+            case ' ':
+            case '"': case '\'': case '`':
+            case '=': case '<': case '>':
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    protected boolean isWhitespace(char ch) {
+        return Character.isWhitespace(ch);
+    }
+
+    protected void skipWhitespace() {
+        while (isWhitespace(ch)) {
+            nextChar();
+        }
+    }
+
+    /**
+     * @param start position of first character of string
+     * @param end position of character beyond last character to be included
+     */
+    String newString(int start, int end) {
+        return new String(buf, start, end - start);
+    }
+
+    static abstract class TagParser {
+        enum Kind { INLINE, BLOCK }
+
+        final Kind kind;
+        final String name;
+
+
+        TagParser(Kind k, String tk) {
+            kind = k;
+            name = tk;
+        }
+
+        TagParser(Kind k, String tk, boolean retainWhiteSpace) {
+            this(k, tk);
+        }
+
+        Kind getKind() {
+            return kind;
+        }
+
+        String getName() {
+            return name;
+        }
+
+        abstract void parse(int pos) throws ParseException;
+    }
+
+    /**
+     * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a>
+     */
+    @SuppressWarnings("deprecation")
+    private void initTagParsers() {
+        TagParser[] parsers = {
+            // @author name-text
+            new TagParser(Kind.BLOCK, "author") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // {@code text}
+            new TagParser(Kind.INLINE, "code", true) {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
+                    nextChar();
+                }
+            },
+
+            // @deprecated deprecated-text
+            new TagParser(Kind.BLOCK, "deprecated") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // {@docRoot}
+            new TagParser(Kind.INLINE, "docRoot") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    if (ch == '}') {
+                        nextChar();
+                        return;
+                    }
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
+                    nextChar();
+                    throw new ParseException("dc.unexpected.content");
+                }
+            },
+
+            // @exception class-name description
+            new TagParser(Kind.BLOCK, "exception") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    skipWhitespace();
+                    reference(false);
+                    blockContent();
+                }
+            },
+
+            // @hidden hidden-text
+            new TagParser(Kind.BLOCK, "hidden") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // @index search-term options-description
+            new TagParser(Kind.INLINE, "index") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    skipWhitespace();
+                    if (ch == '}') {
+                        throw new ParseException("dc.no.content");
+                    }
+                    if (ch == '"') quotedString(); else inlineWord();
+                    skipWhitespace();
+                    if (ch != '}') {
+                        inlineContent();
+                    } else {
+                        nextChar();
+                    }
+                }
+            },
+
+            // {@inheritDoc}
+            new TagParser(Kind.INLINE, "inheritDoc") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    if (ch == '}') {
+                        nextChar();
+                        return;
+                    }
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
+                    nextChar();
+                    throw new ParseException("dc.unexpected.content");
+                }
+            },
+
+            // {@link package.class#member label}
+            new TagParser(Kind.INLINE, "link") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    reference(true);
+                    inlineContent();
+                }
+            },
+
+            // {@linkplain package.class#member label}
+            new TagParser(Kind.INLINE, "linkplain") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    reference(true);
+                    inlineContent();
+                }
+            },
+
+            // {@literal text}
+            new TagParser(Kind.INLINE, "literal", true) {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
+                    nextChar();
+                }
+            },
+
+            // @param parameter-name description
+            new TagParser(Kind.BLOCK, "param") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    skipWhitespace();
+
+                    boolean typaram = false;
+                    if (ch == '<') {
+                        typaram = true;
+                        nextChar();
+                    }
+
+                    identifier();
+
+                    if (typaram) {
+                        if (ch != '>')
+                            throw new ParseException("dc.gt.expected");
+                        nextChar();
+                    }
+
+                    skipWhitespace();
+                    blockContent();
+                }
+            },
+
+            // @return description
+            new TagParser(Kind.BLOCK, "return") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // @see reference | quoted-string | HTML
+            new TagParser(Kind.BLOCK, "see") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    skipWhitespace();
+                    switch (ch) {
+                        case '"':
+                            quotedString();
+                            skipWhitespace();
+                            if (ch == '@'
+                                    || ch == EOI && bp == buf.length - 1) {
+                                return;
+                            }
+                            break;
+
+                        case '<':
+                            blockContent();
+                            return;
+
+                        case '@':
+                            if (newline)
+                                throw new ParseException("dc.no.content");
+                            break;
+
+                        case EOI:
+                            if (bp == buf.length - 1)
+                                throw new ParseException("dc.no.content");
+                            break;
+
+                        default:
+                            if (isJavaIdentifierStart(ch) || ch == '#') {
+                                reference(true);
+                                blockContent();
+                            }
+                    }
+                    throw new ParseException("dc.unexpected.content");
+                }
+            },
+
+            // @serialData data-description
+            new TagParser(Kind.BLOCK, "@serialData") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // @serialField field-name field-type description
+            new TagParser(Kind.BLOCK, "serialField") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    skipWhitespace();
+                    identifier();
+                    skipWhitespace();
+                    reference(false);
+                    if (isWhitespace(ch)) {
+                        skipWhitespace();
+                        blockContent();
+                    }
+                }
+            },
+
+            // @serial field-description | include | exclude
+            new TagParser(Kind.BLOCK, "serial") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // @since since-text
+            new TagParser(Kind.BLOCK, "since") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+
+            // @throws class-name description
+            new TagParser(Kind.BLOCK, "throws") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    skipWhitespace();
+                    reference(false);
+                    blockContent();
+                }
+            },
+
+            // {@value package.class#field}
+            new TagParser(Kind.INLINE, "value") {
+                @Override
+                public void parse(int pos) throws ParseException {
+                    reference(true);
+                    skipWhitespace();
+                    if (ch == '}') {
+                        nextChar();
+                        return;
+                    }
+                    nextChar();
+                    throw new ParseException("dc.unexpected.content");
+                }
+            },
+
+            // @version version-text
+            new TagParser(Kind.BLOCK, "version") {
+                @Override
+                public void parse(int pos) {
+                    blockContent();
+                }
+            },
+        };
+
+        tagParsers = new HashMap<>();
+        for (TagParser p: parsers)
+            tagParsers.put(p.getName(), p);
+
+    }
+
+    private void initEventAttrs() {
+        eventAttrs = new HashSet<>(Arrays.asList(
+            // See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler
+            "onabort",  "onblur",  "oncanplay",  "oncanplaythrough",
+            "onchange",  "onclick",  "oncontextmenu",  "ondblclick",
+            "ondrag",  "ondragend",  "ondragenter",  "ondragleave",
+            "ondragover",  "ondragstart",  "ondrop",  "ondurationchange",
+            "onemptied",  "onended",  "onerror",  "onfocus",  "oninput",
+            "oninvalid",  "onkeydown",  "onkeypress",  "onkeyup",
+            "onload",  "onloadeddata",  "onloadedmetadata",  "onloadstart",
+            "onmousedown",  "onmousemove",  "onmouseout",  "onmouseover",
+            "onmouseup",  "onmousewheel",  "onpause",  "onplay",
+            "onplaying",  "onprogress",  "onratechange",  "onreadystatechange",
+            "onreset",  "onscroll",  "onseeked",  "onseeking",
+            "onselect",  "onshow",  "onstalled",  "onsubmit",  "onsuspend",
+            "ontimeupdate",  "onvolumechange",  "onwaiting",
+
+            // See https://www.w3.org/TR/html4/sgml/dtd.html
+            // Most of the attributes that take a %Script are also defined as event handlers
+            // in HTML 5. The one exception is onunload.
+            // "onchange",  "onclick",   "ondblclick",  "onfocus",
+            // "onkeydown",  "onkeypress",  "onkeyup",  "onload",
+            // "onmousedown",  "onmousemove",  "onmouseout",  "onmouseover",
+            // "onmouseup",  "onreset",  "onselect",  "onsubmit",
+            "onunload"
+        ));
+    }
+
+    private void initURIAttrs() {
+        uriAttrs = new HashSet<>(Arrays.asList(
+            // See https://www.w3.org/TR/html4/sgml/dtd.html
+            //     https://www.w3.org/TR/html5/
+            // These are all the attributes that take a %URI or a valid URL potentially surrounded
+            // by spaces
+            "action",  "cite",  "classid",  "codebase",  "data",
+            "datasrc",  "for",  "href",  "longdesc",  "profile",
+            "src",  "usemap"
+        ));
+    }
+
+}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -36,6 +36,7 @@
 import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.Kinds.Kind.*;
+import com.sun.tools.javac.main.JavaCompiler;
 
 /**
  *  Javadoc's own enter phase does a few things above and beyond that
@@ -65,16 +66,19 @@
         super(context);
         messager = Messager.instance0(context);
         docenv = DocEnv.instance(context);
+        compiler = JavaCompiler.instance(context);
     }
 
     final Messager messager;
     final DocEnv docenv;
+    final JavaCompiler compiler;
 
     @Override
     public void main(List<JCCompilationUnit> trees) {
         // count all Enter errors as warnings.
         int nerrors = messager.nerrors;
         super.main(trees);
+        compiler.enterDone();
         messager.nwarnings += (messager.nerrors - nerrors);
         messager.nerrors = nerrors;
     }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -219,7 +219,6 @@
             // Enter symbols for all files
             docenv.notice("main.Building_tree");
             javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
-            enterDone = true;
         } catch (Abort ex) {}
 
         if (messager.nerrors() != 0)
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -383,6 +383,10 @@
         env.initDoclint(opts, customTagNames, htmlVersion);
     }
 
+    public JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) {
+        return env.initJavaScriptScanner(allowScriptInComments);
+    }
+
     public boolean isFunctionalInterface(AnnotationDesc annotationDesc) {
         return env.source.allowLambda()
             && annotationDesc.annotationType().qualifiedName().equals(
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Fri Jan 20 19:10:00 2017 +0000
@@ -145,6 +145,8 @@
 javadoc.Body_missing_from_html_file=Body tag missing from HTML file
 javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
 javadoc.Multiple_package_comments=Multiple sources of package comments found for package "{0}"
+javadoc.JavaScript_in_comment=JavaScript found in documentation comment.\n\
+    Use --allow-script-in-comments to allow use of JavaScript.
 javadoc.class_not_found=Class {0} not found.
 javadoc.error=error
 javadoc.warning=warning
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java	Fri Jan 20 19:10:00 2017 +0000
@@ -296,9 +296,21 @@
                 return false;
             }
         }
+
+        // In a more object-oriented world, this would be done by methods on the Option objects.
+        // Note that -windowtitle silently removes any and all HTML elements, and so does not need
+        // to be handled here.
+        utils.checkJavaScriptInOption("-header", header);
+        utils.checkJavaScriptInOption("-footer", footer);
+        utils.checkJavaScriptInOption("-top", top);
+        utils.checkJavaScriptInOption("-bottom", bottom);
+        utils.checkJavaScriptInOption("-doctitle", doctitle);
+        utils.checkJavaScriptInOption("-packagesheader", packagesheader);
+
         return true;
     }
 
+
     @Override
     public boolean finishOptionSettings() {
         if (!validateOptions()) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Fri Jan 20 19:10:00 2017 +0000
@@ -363,6 +363,9 @@
 doclet.usage.no-frames.description=\
     Disable the use of frames in the generated output
 
+doclet.usage.allow-script-in-comments.description=\
+    Allow JavaScript in options and comments
+
 doclet.usage.xdocrootparent.parameters=\
     <url>
 doclet.usage.xdocrootparent.description=\
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java	Fri Jan 20 19:10:00 2017 +0000
@@ -40,6 +40,7 @@
 import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
 import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
+import jdk.javadoc.internal.doclets.toolkit.util.UncheckedDocletException;
 import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
 import jdk.javadoc.internal.doclets.toolkit.util.PackageListWriter;
 import jdk.javadoc.internal.doclets.toolkit.util.ResourceIOException;
@@ -112,8 +113,12 @@
         }
 
         try {
-            startGeneration(docEnv);
-            return true;
+            try {
+                startGeneration(docEnv);
+                return true;
+            } catch (UncheckedDocletException e) {
+                throw (DocletException) e.getCause();
+            }
 
         } catch (DocFileIOException e) {
             switch (e.mode) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -34,6 +34,21 @@
 
 package jdk.javadoc.internal.doclets.toolkit;
 
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
 import com.sun.source.doctree.IdentifierTree;
@@ -43,17 +58,8 @@
 import com.sun.source.util.DocTreePath;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.TreePath;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.util.Elements;
-import javax.tools.FileObject;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
 
 public class CommentUtils {
@@ -168,10 +174,18 @@
      */
     public DocCommentDuo getHtmlCommentDuo(Element e) {
         FileObject fo = null;
-        if (e.getKind().equals(ElementKind.OTHER)) {
-            fo = configuration.getOverviewPath();
-        } else if (e.getKind().equals(ElementKind.PACKAGE)) {
-            fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
+        PackageElement pe = null;
+        switch (e.getKind()) {
+            case OTHER:
+                fo = configuration.getOverviewPath();
+                pe = configuration.workArounds.getUnnamedPackage();
+                break;
+            case PACKAGE:
+                fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
+                pe = (PackageElement)e;
+                break;
+            default:
+                return null;
         }
         if (fo == null) {
             return null;
@@ -181,10 +195,20 @@
         if (dcTree == null) {
             return null;
         }
-        DocTreePath treePath = trees.getDocTreePath(fo);
+        DocTreePath treePath = trees.getDocTreePath(fo, pe);
         return new DocCommentDuo(treePath.getTreePath(), dcTree);
     }
 
+    public DocCommentTree parse(URI uri, String text) {
+        return trees.getDocCommentTree(new SimpleJavaFileObject(
+                uri, JavaFileObject.Kind.SOURCE) {
+            @Override @DefinedBy(Api.COMPILER)
+            public CharSequence getCharContent(boolean ignoreEncoding) {
+                return text;
+            }
+        });
+    }
+
     public void setDocCommentTree(Element element, List<DocTree> fullBody,
             List<DocTree> blockTags, Utils utils) {
         DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java	Fri Jan 20 19:10:00 2017 +0000
@@ -228,6 +228,11 @@
     public boolean showversion = false;
 
     /**
+     * Allow JavaScript in doc comments.
+     */
+    private boolean allowScriptInComments = false;
+
+    /**
      * Sourcepath from where to read the source files. Default is classpath.
      *
      */
@@ -646,6 +651,13 @@
                     dumpOnError = true;
                     return true;
                 }
+            },
+            new Option(resources, "--allow-script-in-comments") {
+                @Override
+                public boolean process(String opt, List<String> args) {
+                    allowScriptInComments = true;
+                    return true;
+                }
             }
         };
         Set<Doclet.Option> set = new TreeSet<>();
@@ -1054,7 +1066,7 @@
         private final int argCount;
 
         protected Option(Resources resources, String name, int argCount) {
-            this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-*", ""), name, argCount);
+            this(resources, "doclet.usage." + name.toLowerCase().replaceAll("^-+", ""), name, argCount);
         }
 
         protected Option(Resources resources, String keyBase, String name, int argCount) {
@@ -1228,4 +1240,13 @@
             }
         }
     }
+
+    /**
+     * Returns whether or not to allow JavaScript in comments.
+     * Default is off; can be set true from a command line option.
+     * @return the allowScriptInComments
+     */
+    public boolean isAllowScriptInComments() {
+        return allowScriptInComments;
+    }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java	Fri Jan 20 19:10:00 2017 +0000
@@ -44,6 +44,7 @@
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
 import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
 
@@ -59,7 +60,9 @@
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Env;
 import com.sun.tools.javac.model.JavacElements;
@@ -192,11 +195,24 @@
         return ((VarSymbol)ve).getConstValue();
     }
 
-    //TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
+    // TODO: DocTrees: Trees.getPath(Element e) is slow a factor 4-5 times.
     public Map<Element, TreePath> getElementToTreePath() {
         return toolEnv.elementToTreePath;
     }
 
+    // TODO: we need ElementUtils.getPackage to cope with input strings
+    // to return the proper unnamedPackage for all supported releases.
+    PackageElement getUnnamedPackage() {
+        return (toolEnv.source.allowModules())
+                ? toolEnv.syms.unnamedModule.unnamedPackage
+                : toolEnv.syms.noModule.unnamedPackage;
+    }
+
+    // TODO: implement in either jx.l.m API (preferred) or DocletEnvironment.
+    FileObject getJavaFileObject(PackageElement packageElement) {
+        return ((PackageSymbol)packageElement).sourcefile;
+    }
+
     // TODO: needs to ported to jx.l.m.
     public TypeElement searchClass(TypeElement klass, String className) {
         // search by qualified name first
@@ -530,12 +546,6 @@
         }
     }
 
-    // TODO: this is a fast way to get the JavaFileObject for
-    // a package.html file, however we need to eliminate this.
-    public JavaFileObject getJavaFileObject(PackageElement pe) {
-        return toolEnv.pkgToJavaFOMap.get(pe);
-    }
-
     // TODO: we need to eliminate this, as it is hacky.
     /**
      * Returns a representation of the package truncated to two levels.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java	Fri Jan 20 19:10:00 2017 +0000
@@ -35,6 +35,7 @@
 import jdk.javadoc.internal.doclets.toolkit.DocletException;
 import jdk.javadoc.internal.doclets.toolkit.Messages;
 import jdk.javadoc.internal.doclets.toolkit.Resources;
+import jdk.javadoc.internal.doclets.toolkit.util.UncheckedDocletException;
 import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
 import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException;
 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
@@ -167,6 +168,8 @@
             Throwable cause = e.getCause();
             if (cause instanceof DocletException) {
                 throw (DocletException) cause;
+            } else if (cause instanceof UncheckedDocletException) {
+                throw (DocletException) cause.getCause();
             } else {
                 // use InternalException, so that a stacktrace showing the position of
                 // the internal exception is generated
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties	Fri Jan 20 19:10:00 2017 +0000
@@ -42,6 +42,10 @@
 doclet.Building_Index=Building index for all the packages and classes...
 doclet.Building_Index_For_All_Classes=Building index for all classes...
 doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0.
+doclet.JavaScript_in_comment=JavaScript found in documentation comment.\n\
+Use --allow-script-in-comments to allow use of JavaScript.
+doclet.JavaScript_in_option=option {0} contains JavaScript.\n\
+Use --allow-script-in-comments to allow use of JavaScript.
 doclet.Packages=Packages
 doclet.Modules=Modules
 doclet.Other_Packages=Other Packages
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css	Fri Jan 20 19:10:00 2017 +0000
@@ -250,17 +250,19 @@
     padding:5px 0 0 0;
 }
 .indexNav {
-    margin:10px;
     position:relative;
+    font-size:12px;
+    background-color:#dee3e9;
 }
 .indexNav ul {
-    padding:0;
-    margin:0;
+    margin-top:0;
+    padding:5px;
 }
 .indexNav ul li {
     display:inline;
     list-style-type:none;
     padding-right:10px;
+    text-transform:uppercase;
 }
 .indexNav h1 {
     font-size:13px;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/JavaScriptScanner.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.javadoc.internal.doclets.toolkit.util;
+
+
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Consumer;
+
+import com.sun.source.doctree.AttributeTree;
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.DocTree.Kind;
+import com.sun.source.doctree.StartElementTree;
+import com.sun.source.util.DocTreePath;
+import com.sun.source.util.DocTreePathScanner;
+import com.sun.source.util.TreePath;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+
+/**
+ * A DocTree scanner to detect use of JavaScript in a doc comment tree.
+ */
+public class JavaScriptScanner extends DocTreePathScanner<Void, Consumer<DocTreePath>> {
+
+    public Void scan(DocCommentTree tree, TreePath p, Consumer<DocTreePath> f) {
+        return scan(new DocTreePath(p, tree), f);
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitStartElement(StartElementTree tree, Consumer<DocTreePath> f) {
+        String name = tree.getName().toString();
+        if (name.equalsIgnoreCase("script"))
+            f.accept(getCurrentPath());
+        return super.visitStartElement(tree, f);
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitAttribute(AttributeTree tree, Consumer<DocTreePath> f) {
+        String name = tree.getName().toString().toLowerCase(Locale.ENGLISH);
+        switch (name) {
+            // See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler
+            case "onabort":  case "onblur":  case "oncanplay":  case "oncanplaythrough":
+            case "onchange":  case "onclick":  case "oncontextmenu":  case "ondblclick":
+            case "ondrag":  case "ondragend":  case "ondragenter":  case "ondragleave":
+            case "ondragover":  case "ondragstart":  case "ondrop":  case "ondurationchange":
+            case "onemptied":  case "onended":  case "onerror":  case "onfocus":  case "oninput":
+            case "oninvalid":  case "onkeydown":  case "onkeypress":  case "onkeyup":
+            case "onload":  case "onloadeddata":  case "onloadedmetadata":  case "onloadstart":
+            case "onmousedown":  case "onmousemove":  case "onmouseout":  case "onmouseover":
+            case "onmouseup":  case "onmousewheel":  case "onpause":  case "onplay":
+            case "onplaying":  case "onprogress":  case "onratechange":  case "onreadystatechange":
+            case "onreset":  case "onscroll":  case "onseeked":  case "onseeking":
+            case "onselect":  case "onshow":  case "onstalled":  case "onsubmit":  case "onsuspend":
+            case "ontimeupdate":  case "onvolumechange":  case "onwaiting":
+
+            // See https://www.w3.org/TR/html4/sgml/dtd.html
+            // Most of the attributes that take a %Script are also defined as event handlers
+            // in HTML 5. The one exception is onunload.
+            // case "onchange":  case "onclick":   case "ondblclick":  case "onfocus":
+            // case "onkeydown":  case "onkeypress":  case "onkeyup":  case "onload":
+            // case "onmousedown":  case "onmousemove":  case "onmouseout":  case "onmouseover":
+            // case "onmouseup":  case "onreset":  case "onselect":  case "onsubmit":
+            case "onunload":
+                f.accept(getCurrentPath());
+                break;
+
+            // See https://www.w3.org/TR/html4/sgml/dtd.html
+            //     https://www.w3.org/TR/html5/
+            // These are all the attributes that take a %URI or a valid URL potentially surrounded
+            // by spaces
+            case "action":  case "cite":  case "classid":  case "codebase":  case "data":
+            case "datasrc":  case "for":  case "href":  case "longdesc":  case "profile":
+            case "src":  case "usemap":
+                List<? extends DocTree> value = tree.getValue();
+                if (!value.isEmpty() && value.get(0).getKind() == Kind.TEXT) {
+                    String v = value.get(0).toString().trim().toLowerCase(Locale.ENGLISH);
+                    if (v.startsWith("javascript:")) {
+                        f.accept(getCurrentPath());
+                    }
+                }
+                break;
+        }
+        return super.visitAttribute(tree, f);
+    }
+
+    /**
+     * Used to indicate a fault when parsing, typically used in
+     * lambda methods.
+     */
+    public static class Fault extends RuntimeException {
+        private static final long serialVersionUID = 0L;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/UncheckedDocletException.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.doclets.toolkit.util;
+
+import jdk.javadoc.internal.doclets.toolkit.DocletException;
+
+/**
+ * An unchecked exception that wraps a DocletException.
+ * It can be used in places where a checked exception
+ * is not permitted, such as in lambda expressions.
+ *
+ *  <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 UncheckedDocletException extends Error {
+    private static final long serialVersionUID = -9131058909576418984L;
+
+    public UncheckedDocletException(DocletException de) {
+        super(de);
+    }
+
+    @Override
+    public synchronized Throwable getCause() {
+        return super.getCause();
+    }
+
+    @Override
+    public synchronized Throwable initCause(Throwable cause) {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Fri Jan 20 19:10:00 2017 +0000
@@ -27,6 +27,7 @@
 
 import java.lang.annotation.Documented;
 import java.lang.ref.SoftReference;
+import java.net.URI;
 import java.text.CollationKey;
 import java.text.Collator;
 import java.util.*;
@@ -108,6 +109,7 @@
     public final DocTrees docTrees;
     public final Elements elementUtils;
     public final Types typeUtils;
+    public final JavaScriptScanner javaScriptScanner;
 
     public Utils(Configuration c) {
         configuration = c;
@@ -115,6 +117,7 @@
         elementUtils = c.docEnv.getElementUtils();
         typeUtils = c.docEnv.getTypeUtils();
         docTrees = c.docEnv.getDocTrees();
+        javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
     }
 
     // our own little symbol table
@@ -3025,6 +3028,16 @@
         TreePath path = isValidDuo(duo) ? duo.treePath : null;
         if (!dcTreeCache.containsKey(element)) {
             if (docCommentTree != null && path != null) {
+                if (!configuration.isAllowScriptInComments()) {
+                    try {
+                        javaScriptScanner.scan(docCommentTree, path, p -> {
+                            throw new JavaScriptScanner.Fault();
+                        });
+                    } catch (JavaScriptScanner.Fault jsf) {
+                        String text = configuration.getText("doclet.JavaScript_in_comment");
+                        throw new UncheckedDocletException(new SimpleDocletException(text, jsf));
+                    }
+                }
                 configuration.workArounds.runDocLint(path);
             }
             dcTreeCache.put(element, duo);
@@ -3044,6 +3057,21 @@
         return null;
     }
 
+    public void checkJavaScriptInOption(String name, String value) {
+        if (!configuration.isAllowScriptInComments()) {
+            DocCommentTree dct = configuration.cmtUtils.parse(
+                    URI.create("option://" + name.replace("-", "")), "<body>" + value + "</body>");
+            try {
+                javaScriptScanner.scan(dct, null, p -> {
+                    throw new JavaScriptScanner.Fault();
+                });
+            } catch (JavaScriptScanner.Fault jsf) {
+                String text = configuration.getText("doclet.JavaScript_in_option", name);
+                throw new UncheckedDocletException(new SimpleDocletException(text, jsf));
+            }
+        }
+    }
+
     boolean isValidDuo(DocCommentDuo duo) {
         return duo != null && duo.dcTree != null;
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -39,14 +39,12 @@
 
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.ModuleElement.ExportsDirective;
 import javax.lang.model.element.ModuleElement.RequiresDirective;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
 import javax.lang.model.util.ElementFilter;
 import javax.lang.model.util.SimpleElementVisitor9;
 import javax.tools.JavaFileManager;
@@ -54,15 +52,12 @@
 import javax.tools.JavaFileObject;
 import javax.tools.StandardLocation;
 
-import com.sun.tools.javac.code.Flags;
 import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.comp.Modules;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@@ -75,9 +70,11 @@
 import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
 
 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static javax.tools.JavaFileObject.Kind.*;
 import static jdk.javadoc.internal.tool.Main.Result.*;
 import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
 
+
 /**
  * This class manages elements specified on the command line, and
  * produces "specified" and "included" data sets, needed by the
@@ -864,7 +861,7 @@
     }
 
     private boolean isTypeElementSelected(TypeElement te) {
-        return (xclasses || toolEnv.isFromSource(te)) && isSelected(te);
+        return (xclasses || toolEnv.getFileKind(te) == SOURCE) && isSelected(te);
     }
 
     SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocClassFinder.java	Fri Jan 20 19:10:00 2017 +0000
@@ -88,8 +88,7 @@
     @Override
     protected void extraFileActions(PackageSymbol pack, JavaFileObject fo) {
         if (fo.isNameCompatible("package", JavaFileObject.Kind.HTML)) {
-            toolEnv.pkgToJavaFOMap.put(pack, fo);
-            trees.putJavaFileObject(pack, fo);
+            pack.sourcefile = fo;
         }
     }
 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocEnter.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocEnter.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -36,6 +36,7 @@
 import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.Kinds.Kind.*;
+import com.sun.tools.javac.main.JavaCompiler;
 
 /**
  *  Javadoc's own enter phase does a few things above and beyond that
@@ -64,16 +65,19 @@
         super(context);
         messager = Messager.instance0(context);
         toolEnv = ToolEnvironment.instance(context);
+        compiler = JavaCompiler.instance(context);
     }
 
     final Messager messager;
     final ToolEnvironment toolEnv;
+    final JavaCompiler compiler;
 
     @Override
     public void main(List<JCCompilationUnit> trees) {
         // count all Enter errors as warnings.
         int nerrors = messager.nerrors;
         super.main(trees);
+        compiler.enterDone();
         messager.nwarnings += (messager.nerrors - nerrors);
         messager.nerrors = nerrors;
     }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -202,7 +202,6 @@
             javadocEnter.main(classTrees.toList().appendList(packageTrees));
             etable.setClassDeclList(listClasses(classTrees.toList()));
 
-            enterDone = true;
             etable.analyze();
         } catch (CompletionFailure cf) {
             throw new ToolException(ABNORMAL, cf.getMessage(), cf);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Messager.java	Fri Jan 20 19:10:00 2017 +0000
@@ -182,7 +182,7 @@
     }
 
     private String getDiagSource(DocTreePath path) {
-        if (path == null) {
+        if (path == null || path.getTreePath() == null) {
             return programName;
         }
         JavacTrees trees = JavacTrees.instance(context);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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,7 +29,6 @@
 import java.util.*;
 
 import javax.lang.model.element.Element;
-import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.util.Elements;
 import javax.tools.JavaFileManager;
@@ -116,8 +115,6 @@
 
     WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<>();
 
-    public final HashMap<PackageElement, JavaFileObject> pkgToJavaFOMap = new HashMap<>();
-
     /** Allow documenting from class files? */
     boolean docClasses = false;
 
@@ -193,21 +190,11 @@
         elementToTreePath.put(e, tree);
     }
 
-    /**
-     * Returns true if the type element originates from source.
-     * Primarily used to disambiguate a type element associated with a source
-     * file versus a class file.
-     * @param te the type element
-     * @return true if the symbol is from source
-     */
-    public boolean isFromSource(TypeElement te) {
-        return getFileKind(te) == Kind.SOURCE;
-    }
-
     public Kind getFileKind(TypeElement te) {
         JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile;
         return jfo == null ? Kind.SOURCE : jfo.getKind();
     }
+
     /**
      * Print a notice, iff <em>quiet</em> is not specified.
      *
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ModuleResolution_attribute.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ModuleResolution_attribute.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -50,7 +50,7 @@
     public ModuleResolution_attribute(ConstantPool constant_pool,
                               int resolution_flags)
             throws ConstantPoolException {
-        this(constant_pool.getUTF8Index(Attribute.ModulePackages),
+        this(constant_pool.getUTF8Index(Attribute.ModuleResolution),
              resolution_flags);
     }
 
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Fri Jan 20 19:10:00 2017 +0000
@@ -128,9 +128,8 @@
  */
 public class JShellTool implements MessageHandler {
 
-    private static final String LINE_SEP = System.getProperty("line.separator");
     private static final Pattern LINEBREAK = Pattern.compile("\\R");
-    private static final String RECORD_SEPARATOR = "\u241E";
+            static final String RECORD_SEPARATOR = "\u241E";
     private static final String RB_NAME_PREFIX  = "jdk.internal.jshell.tool.resources";
     private static final String VERSION_RB_NAME = RB_NAME_PREFIX + ".version";
     private static final String L10N_RB_NAME    = RB_NAME_PREFIX + ".l10n";
@@ -199,7 +198,7 @@
     private boolean debug = false;
     public boolean testPrompt = false;
     private String defaultStartup = null;
-    private String startup = null;
+    private Startup startup = null;
     private String executionControlSpec = null;
     private EditorSetting editor = BUILT_IN_EDITOR;
 
@@ -216,7 +215,6 @@
     static final String MODE_KEY     = "MODE";
     static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE";
 
-    static final String DEFAULT_STARTUP_NAME = "DEFAULT";
     static final Pattern BUILTIN_FILE_PATTERN = Pattern.compile("\\w+");
     static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh";
 
@@ -431,13 +429,13 @@
         private final OptionSpecBuilder argX = parser.accepts("X");
 
         private String feedbackMode = null;
-        private String initialStartup = null;
+        private Startup initialStartup = null;
 
         String feedbackMode() {
             return feedbackMode;
         }
 
-        String startup() {
+        Startup startup() {
             return initialStartup;
         }
 
@@ -485,22 +483,15 @@
                     startmsg("jshell.err.opt.startup.conflict");
                     return null;
                 }
-                StringBuilder sb = new StringBuilder();
-                for (String fn : sts) {
-                    String s = readFile(fn, "--startup");
-                    if (s == null) {
-                        return null;
-                    }
-                    sb.append(s);
+                initialStartup = Startup.fromFileList(sts, "--startup", new InitMessageHandler());
+                if (initialStartup == null) {
+                    return null;
                 }
-                initialStartup = sb.toString();
             } else if (options.has(argNoStart)) {
-                initialStartup = "";
+                initialStartup = Startup.noStartup();
             } else {
-                initialStartup = prefs.get(STARTUP_KEY);
-                if (initialStartup == null) {
-                    initialStartup = defaultStartup();
-                }
+                String packedStartup = prefs.get(STARTUP_KEY);
+                initialStartup = Startup.unpack(packedStartup, new InitMessageHandler());
             }
             if (options.has(argExecution)) {
                 executionControlSpec = options.valueOf(argExecution);
@@ -639,6 +630,11 @@
             return "";
         }
         String pp = s.replaceAll("\\R", post + pre);
+        if (pp.endsWith(post + pre)) {
+            // prevent an extra prefix char and blank line when the string
+            // already terminates with newline
+            pp = pp.substring(0, pp.length() - (post + pre).length());
+        }
         return pre + pp + post;
     }
 
@@ -893,7 +889,7 @@
         analysis = state.sourceCodeAnalysis();
         live = true;
 
-        startUpRun(startup);
+        startUpRun(startup.toString());
         currentNameSpace = mainNamespace;
     }
 
@@ -1077,7 +1073,7 @@
                        .toArray(Command[]::new);
     }
 
-    private static Path toPathResolvingUserHome(String pathString) {
+    static Path toPathResolvingUserHome(String pathString) {
         if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
             return Paths.get(System.getProperty("user.home"), pathString.substring(2));
         else
@@ -1838,48 +1834,43 @@
             return true;
         }
         if (hasFile) {
-            StringBuilder sb = new StringBuilder();
-            for (String fn : fns) {
-                String s = readFile(fn, "/set start");
-                if (s == null) {
-                    return false;
-                }
-                sb.append(s);
+            startup = Startup.fromFileList(fns, "/set start", this);
+            if (startup == null) {
+                return false;
             }
-            startup = sb.toString();
         } else if (defaultOption) {
-            startup = defaultStartup();
+            startup = Startup.defaultStartup(this);
         } else if (noneOption) {
-            startup = "";
+            startup = Startup.noStartup();
         }
         if (retainOption) {
             // retain startup setting
-            prefs.put(STARTUP_KEY, startup);
+            prefs.put(STARTUP_KEY, startup.storedForm());
         }
         return true;
     }
 
+    // show the "/set start" settings (retained and, if different, current)
+    // as commands (and file contents).  All commands first, then contents.
     void showSetStart() {
+        StringBuilder sb = new StringBuilder();
         String retained = prefs.get(STARTUP_KEY);
         if (retained != null) {
-            showSetStart(true, retained);
-        }
-        if (retained == null || !startup.equals(retained)) {
-            showSetStart(false, startup);
+            Startup retainedStart = Startup.unpack(retained, this);
+            boolean currentDifferent = !startup.equals(retainedStart);
+            sb.append(retainedStart.show(true));
+            if (currentDifferent) {
+                sb.append(startup.show(false));
+            }
+            sb.append(retainedStart.showDetail());
+            if (currentDifferent) {
+                sb.append(startup.showDetail());
+            }
+        } else {
+            sb.append(startup.show(false));
+            sb.append(startup.showDetail());
         }
-    }
-
-    void showSetStart(boolean isRetained, String start) {
-        String cmd = "/set start" + (isRetained ? " -retain " : " ");
-        String stset;
-        if (start.equals(defaultStartup())) {
-            stset = cmd + "-default";
-        } else if (start.isEmpty()) {
-            stset = cmd + "-none";
-        } else {
-            stset = "startup.jsh:\n" + start + "\n" + cmd + "startup.jsh";
-        }
-        hard(stset);
+        hard(sb.toString());
     }
 
     boolean cmdDebug(String arg) {
@@ -2200,13 +2191,22 @@
                 case ASSIGNMENT_SUBKIND:
                 case OTHER_EXPRESSION_SUBKIND:
                 case TEMP_VAR_EXPRESSION_SUBKIND:
-                case STATEMENT_SUBKIND:
                 case UNKNOWN_SUBKIND:
                     if (!src.endsWith(";")) {
                         src = src + ";";
                     }
                     srcSet.add(src);
                     break;
+                case STATEMENT_SUBKIND:
+                    if (src.endsWith("}")) {
+                        // Could end with block or, for example, new Foo() {...}
+                        // so, we need deeper analysis to know if it needs a semicolon
+                        src = analysis.analyzeCompletion(src).source();
+                    } else if (!src.endsWith(";")) {
+                        src = src + ";";
+                    }
+                    srcSet.add(src);
+                    break;
                 default:
                     srcSet.add(src);
                     break;
@@ -2380,38 +2380,7 @@
         return false;
     }
 
-    /**
-     * Read an external file. Error messages accessed via keyPrefix
-     *
-     * @param filename file to access or null
-     * @param context printable non-natural language context for errors
-     * @return contents of file as string
-     */
-    String readFile(String filename, String context) {
-        if (filename != null) {
-            try {
-                byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
-                return new String(encoded);
-            } catch (AccessDeniedException e) {
-                errormsg("jshell.err.file.not.accessible", context, filename, e.getMessage());
-            } catch (NoSuchFileException e) {
-                String resource = getResource(filename);
-                if (resource != null) {
-                    // Not found as file, but found as resource
-                    return resource;
-                }
-                errormsg("jshell.err.file.not.found", context, filename);
-            } catch (Exception e) {
-                errormsg("jshell.err.file.exception", context, filename, e);
-            }
-        } else {
-            errormsg("jshell.err.file.filename", context);
-        }
-        return null;
-
-    }
-
-    String getResource(String name) {
+    static String getResource(String name) {
         if (BUILTIN_FILE_PATTERN.matcher(name).matches()) {
             try {
                 return readResource(name);
@@ -2423,33 +2392,16 @@
     }
 
     // Read a built-in file from resources
-    String readResource(String name) throws IOException {
+    static String readResource(String name) throws IOException {
         // Attempt to find the file as a resource
         String spec = String.format(BUILTIN_FILE_PATH_FORMAT, name);
 
         try (InputStream in = JShellTool.class.getResourceAsStream(spec);
-             BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
-            return reader.lines().collect(Collectors.joining("\n"));
+                BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
+            return reader.lines().collect(Collectors.joining("\n", "", "\n"));
         }
     }
 
-    // retrieve the default startup string
-    String defaultStartup() {
-        if (defaultStartup == null) {
-            defaultStartup = ""; // failure case
-            try {
-                defaultStartup = readResource(DEFAULT_STARTUP_NAME);
-            } catch (AccessDeniedException e) {
-                errormsg("jshell.err.file.not.accessible", "jshell", DEFAULT_STARTUP_NAME, e.getMessage());
-            } catch (NoSuchFileException e) {
-                errormsg("jshell.err.file.not.found", "jshell", DEFAULT_STARTUP_NAME);
-            } catch (Exception e) {
-                errormsg("jshell.err.file.exception", "jshell", DEFAULT_STARTUP_NAME, e);
-            }
-        }
-        return defaultStartup;
-    }
-
     private boolean cmdReset(String rawargs) {
         if (!parseCommandLineLikeFlags(rawargs, new OptionParserBase())) {
             return false;
@@ -2551,7 +2503,7 @@
                     writer.write("\n");
                 }
             } else if (at.hasOption("-start")) {
-                writer.append(startup);
+                writer.append(startup.toString());
             } else {
                 String sources = (at.hasOption("-all")
                         ? state.snippets()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Startup.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.tool;
+
+import java.nio.file.AccessDeniedException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+import static jdk.internal.jshell.tool.JShellTool.RECORD_SEPARATOR;
+import static jdk.internal.jshell.tool.JShellTool.getResource;
+import static jdk.internal.jshell.tool.JShellTool.readResource;
+import static jdk.internal.jshell.tool.JShellTool.toPathResolvingUserHome;
+
+/**
+ * Processing start-up "script" information.  The startup may consist of several
+ * entries, each of which may have been read from a user file or be a built-in
+ * resource.  The startup may also be empty ("-none"); Which is stored as the
+ * empty string different from unset (null).  Built-in resources come from
+ * resource files.  Startup is stored as named elements rather than concatenated
+ * text, for display purposes but also importantly so that when resources update
+ * with new releases the built-in will update.
+ * @author Robert Field
+ */
+class Startup {
+
+    // Store one entry in the start-up list
+    private static class StartupEntry {
+
+        // is this a JShell built-in?
+        private final boolean isBuiltIn;
+
+        // the file or resource name
+        private final String name;
+
+        // the commands/snippets as text
+        private final String content;
+
+        // for files, the date/time read in -- makes clear it is a snapshot
+        private final String timeStamp;
+
+        StartupEntry(boolean isBuiltIn, String name, String content) {
+            this(isBuiltIn, name, content, "");
+        }
+
+        StartupEntry(boolean isBuiltIn, String name, String content, String timeStamp) {
+            this.isBuiltIn = isBuiltIn;
+            this.name = name;
+            this.content = content;
+            this.timeStamp = timeStamp;
+        }
+
+        // string form to store in storage (e.g. Preferences)
+        String storedForm() {
+            return (isBuiltIn ? "*" : "-") + RECORD_SEPARATOR +
+                    name + RECORD_SEPARATOR +
+                    timeStamp + RECORD_SEPARATOR +
+                    content + RECORD_SEPARATOR;
+        }
+
+        // the content
+        @Override
+        public String toString() {
+            return content;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 41 * hash + (this.isBuiltIn ? 1 : 0);
+            hash = 41 * hash + Objects.hashCode(this.name);
+            if (!isBuiltIn) {
+                hash = 41 * hash + Objects.hashCode(this.content);
+            }
+            return hash;
+        }
+
+        // built-ins match on name only.  Time stamp isn't considered
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof StartupEntry)) {
+                return false;
+            }
+            StartupEntry sue = (StartupEntry) o;
+            return isBuiltIn == sue.isBuiltIn &&
+                     name.equals(sue.name) &&
+                     (isBuiltIn || content.equals(sue.content));
+        }
+    }
+
+    private static final String DEFAULT_STARTUP_NAME = "DEFAULT";
+
+    // cached DEFAULT start-up
+    private static Startup defaultStartup = null;
+
+    // the list of entries
+    private List<StartupEntry> entries;
+
+    // the concatenated content of the list of entries
+    private String content;
+
+    // created only with factory methods (below)
+    private Startup(List<StartupEntry> entries) {
+        this.entries = entries;
+        this.content = entries.stream()
+                .map(sue -> sue.toString())
+                .collect(joining());
+    }
+
+    private Startup(StartupEntry entry) {
+        this(Collections.singletonList(entry));
+    }
+
+    // retrieve the content
+    @Override
+    public String toString() {
+        return content;
+    }
+
+    @Override
+    public int hashCode() {
+        return 9  + Objects.hashCode(this.entries);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof Startup)
+                && entries.equals(((Startup) o).entries);
+    }
+
+    // are there no entries ("-none")?
+    boolean isEmpty() {
+        return entries.isEmpty();
+    }
+
+    // is this the "-default" setting -- one entry which is DEFAULT
+    boolean isDefault() {
+        if (entries.size() == 1) {
+            StartupEntry sue = entries.get(0);
+            if (sue.isBuiltIn && sue.name.equals(DEFAULT_STARTUP_NAME)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // string form to store in storage (e.g. Preferences)
+    String storedForm() {
+        return entries.stream()
+                .map(sue -> sue.storedForm())
+                .collect(joining());
+    }
+
+    // show commands to re-create
+    String show(boolean isRetained) {
+        String cmd = "/set start " + (isRetained ? "-retain " : "");
+        if (isDefault()) {
+            return cmd + "-default\n";
+        } else if (isEmpty()) {
+            return cmd + "-none\n";
+        } else {
+            return entries.stream()
+                    .map(sue -> sue.name)
+                    .collect(joining(" ", cmd, "\n"));
+        }
+    }
+
+    // show corresponding contents for show()
+    String showDetail() {
+        if (isDefault() || isEmpty()) {
+            return "";
+        } else {
+            return entries.stream()
+                    .map(sue -> "---- " + sue.name
+                            + (sue.timeStamp.isEmpty()
+                                    ? ""
+                                    : " @ " + sue.timeStamp)
+                            + " ----\n" + sue.content)
+                    .collect(joining());
+        }
+    }
+
+    /**
+     * Factory method: Unpack from stored form.
+     *
+     * @param storedForm the Startup in the form as stored on persistent
+     * storage (e.g. Preferences)
+     * @param mh handler for error messages
+     * @return Startup, or default startup when error (message has been printed)
+     */
+    static Startup unpack(String storedForm, MessageHandler mh) {
+        if (storedForm != null) {
+            if (storedForm.isEmpty()) {
+                return noStartup();
+            }
+            try {
+                String[] all = storedForm.split(RECORD_SEPARATOR);
+                if (all.length == 1) {
+                    // legacy (content only)
+                    return new Startup(new StartupEntry(false, "user.jsh", storedForm));
+                } else if (all.length % 4 == 0) {
+                    List<StartupEntry> e = new ArrayList<>(all.length / 4);
+                    for (int i = 0; i < all.length; i += 4) {
+                        final boolean isBuiltIn;
+                        switch (all[i]) {
+                            case "*":
+                                isBuiltIn = true;
+                                break;
+                            case "-":
+                                isBuiltIn = false;
+                                break;
+                            default:
+                                throw new IllegalArgumentException("Unexpected StartupEntry kind: " + all[i]);
+                        }
+                        String name = all[i + 1];
+                        String timeStamp = all[i + 2];
+                        String content = all[i + 3];
+                        if (isBuiltIn) {
+                            // update to current definition, use stored if removed/error
+                            String resource = getResource(name);
+                            if (resource != null) {
+                                content = resource;
+                            }
+                        }
+                        e.add(new StartupEntry(isBuiltIn, name, content, timeStamp));
+                    }
+                    return new Startup(e);
+                } else {
+                    throw new IllegalArgumentException("Unexpected StartupEntry entry count: " + all.length);
+                }
+            } catch (Exception ex) {
+                mh.errormsg("jshell.err.corrupted.stored.startup", ex.getMessage());
+            }
+        }
+        return defaultStartup(mh);
+    }
+
+    /**
+     * Factory method: Read Startup from a list of external files or resources.
+     *
+     * @param fns list of file/resource names to access
+     * @param context printable non-natural language context for errors
+     * @param mh handler for error messages
+     * @return files as Startup, or null when error (message has been printed)
+     */
+    static Startup fromFileList(List<String> fns, String context, MessageHandler mh) {
+        List<StartupEntry> entries = fns.stream()
+                .map(fn -> readFile(fn, context, mh))
+                .collect(toList());
+        if (entries.stream().anyMatch(sue -> sue == null)) {
+            return null;
+        }
+        return new Startup(entries);
+    }
+
+    /**
+     * Read a external file or a resource.
+     *
+     * @param filename file/resource to access
+     * @param context printable non-natural language context for errors
+     * @param mh handler for error messages
+     * @return file as startup entry, or null when error (message has been printed)
+     */
+    private static StartupEntry readFile(String filename, String context, MessageHandler mh) {
+        if (filename != null) {
+            try {
+                byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
+                return new StartupEntry(false, filename, new String(encoded),
+                        LocalDateTime.now().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)));
+            } catch (AccessDeniedException e) {
+                mh.errormsg("jshell.err.file.not.accessible", context, filename, e.getMessage());
+            } catch (NoSuchFileException e) {
+                String resource = getResource(filename);
+                if (resource != null) {
+                    // Not found as file, but found as resource
+                    return new StartupEntry(true, filename, resource);
+                }
+                mh.errormsg("jshell.err.file.not.found", context, filename);
+            } catch (Exception e) {
+                mh.errormsg("jshell.err.file.exception", context, filename, e);
+            }
+        } else {
+            mh.errormsg("jshell.err.file.filename", context);
+        }
+        return null;
+
+    }
+
+    /**
+     * Factory method: The empty Startup ("-none").
+     *
+     * @return the empty Startup
+     */
+    static Startup noStartup() {
+        return new Startup(Collections.emptyList());
+    }
+
+    /**
+     * Factory method: The default Startup ("-default.").
+     *
+     * @param mh handler for error messages
+     * @return The default Startup, or empty startup when error (message has been printed)
+     */
+    static Startup defaultStartup(MessageHandler mh) {
+        if (defaultStartup != null) {
+            return defaultStartup;
+        }
+        try {
+            String content = readResource(DEFAULT_STARTUP_NAME);
+            return defaultStartup = new Startup(
+                    new StartupEntry(true, DEFAULT_STARTUP_NAME, content));
+        } catch (AccessDeniedException e) {
+            mh.errormsg("jshell.err.file.not.accessible", "jshell", DEFAULT_STARTUP_NAME, e.getMessage());
+        } catch (NoSuchFileException e) {
+            mh.errormsg("jshell.err.file.not.found", "jshell", DEFAULT_STARTUP_NAME);
+        } catch (Exception e) {
+            mh.errormsg("jshell.err.file.exception", "jshell", DEFAULT_STARTUP_NAME, e);
+        }
+        return defaultStartup = noStartup();
+    }
+
+}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Fri Jan 20 19:10:00 2017 +0000
@@ -148,6 +148,8 @@
 jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1}
 jshell.err.retained.mode.failure = Failure in retained modes (modes cleared) -- {0} {1}
 
+jshell.err.corrupted.stored.startup = Corrupted stored startup, using default -- {0}
+
 jshell.console.see.more = <press tab to see more>
 jshell.console.see.javadoc = <press shift-tab again to see javadoc>
 jshell.console.see.help = <press shift-tab again to see detailed help>
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/DEFAULT.jsh	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/DEFAULT.jsh	Fri Jan 20 19:10:00 2017 +0000
@@ -8,4 +8,3 @@
 import java.util.prefs.*;
 import java.util.regex.*;
 import java.util.stream.*;
-
--- a/langtools/test/Makefile	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/Makefile	Fri Jan 20 19:10:00 2017 +0000
@@ -378,7 +378,7 @@
 	@rm -f -r $(JCK_COMPILER_OUTPUT_DIR)/work $(JCK_COMPILER_OUTPUT_DIR)/report \
 	    $(JCK_COMPILER_OUTPUT_DIR)/diff.html $(JCK_COMPILER_OUTPUT_DIR)/status.txt
 	@mkdir -p $(JCK_COMPILER_OUTPUT_DIR)
-	$(JT_JAVA)/bin/java -Xmx512m \
+	$(JT_JAVA)/bin/java -Xmx1024m \
 	    -jar $(JCK_HOME)/JCK-compiler-9/lib/jtjck.jar \
 	    $(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
             -r:$(JCK_COMPILER_OUTPUT_DIR)/report \
@@ -429,7 +429,7 @@
 	@rm -f -r $(JCK_RUNTIME_OUTPUT_DIR)/work $(JCK_RUNTIME_OUTPUT_DIR)/report \
 	    $(JCK_RUNTIME_OUTPUT_DIR)/diff.html $(JCK_RUNTIME_OUTPUT_DIR)/status.txt
 	@mkdir -p $(JCK_RUNTIME_OUTPUT_DIR)
-	$(JT_JAVA)/bin/java -Xmx512m \
+	$(JT_JAVA)/bin/java -Xmx1024m \
 	    -jar $(JCK_HOME)/JCK-runtime-9/lib/jtjck.jar \
 	    $(if $(JCK_VERBOSE),$(if $(filter $(JCK_VERBOSE),summary),-v,-v:$(JCK_VERBOSE))) \
             -r:$(JCK_RUNTIME_OUTPUT_DIR)/report \
--- a/langtools/test/TEST.ROOT	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/TEST.ROOT	Fri Jan 20 19:10:00 2017 +0000
@@ -14,8 +14,8 @@
 # Group definitions
 groups=TEST.groups
 
-# Tests using jtreg 4.2 b04 features
-requiredVersion=4.2 b04
+# Tests using jtreg 4.2 b05 features
+requiredVersion=4.2 b05
 
 # Use new module options
 useNewOptions=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/TestScriptInComment.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8138725
+ * @summary test --allow-script-in-comments
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Combo-style test, exercising combinations of different HTML fragments that may contain
+ * JavaScript, different places to place those fragments, and whether or not to allow the use
+ * of JavaScript.
+ */
+public class TestScriptInComment {
+    public static void main(String... args) throws Exception {
+        new TestScriptInComment().run();
+    }
+
+    /**
+     * Representative samples of different fragments of HTML that may contain JavaScript.
+     * To facilitate checking the output manually in a browser, the text "#ALERT" will be
+     * replaced by a JavaScript call of "alert(msg)", using a message string that is specific
+     * to the test case.
+     */
+    enum Comment {
+        LC("<script>#ALERT</script>", true), // script tag in Lower Case
+        UC("<SCRIPT>#ALERT</script>", true), // script tag in Upper Case
+        WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space
+        SP("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute
+        ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute
+        URI("<a href='javascript:#ALERT'>x</a>", true); // javascript URI
+
+        /**
+         * Creates an HTML fragment to be injected into a template.
+         * @param text the HTML fragment to put into a doc comment or option.
+         * @param hasScript whether or not this fragment does contain legal JavaScript
+         * @param opts any additional options to be specified when javadoc is run
+         */
+        Comment(String text, boolean hasScript, String... opts) {
+            this.text = text;
+            this.hasScript = hasScript;
+            this.opts = Arrays.asList(opts);
+        }
+
+        final String text;
+        final boolean hasScript;
+        final List<String> opts;
+    };
+
+    /**
+     * Representative samples of positions in which javadoc may find JavaScript.
+     * Each template contains a series of strings, which are written to files or inferred as options.
+     * The first source file implies a corresponding output file which should not be written
+     * if the comment contains JavaScript and JavaScript is not allowed.
+     */
+    enum Template {
+        OVR("<html><body> overview #COMMENT </body></html>", "package p; public class C { }"),
+        PKGINFO("#COMMENT package p;", "package p; public class C { }"),
+        PKGHTML("<html><body>#COMMENT package p;</body></html>", "package p; public class C { }"),
+        CLS("package p; #COMMENT public class C { }"),
+        CON("package p; public class C { #COMMENT public C() { } }"),
+        FLD("package p; public class C { #COMMENT public int f; }"),
+        MTH("package p; public class C { #COMMENT public void m() { } }"),
+        TOP("-top", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        HDR("-header", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        FTR("-footer", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        BTM("-bottom", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        DTTL("-doctitle", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        PHDR("-packagesheader", "lorem #COMMENT ipsum", "package p; public class C { }");
+
+        Template(String... args) {
+            opts = new ArrayList<String>();
+            sources = new ArrayList<String>();
+            int i = 0;
+            while (args[i].startsWith("-")) {
+                // all options being tested have a single argument that follow the option
+                opts.add(args[i++]);
+                opts.add(args[i++]);
+            }
+            while(i < args.length) {
+                sources.add(args[i++]);
+            }
+        }
+
+        // groups: 1 <html> or not;  2: package name;  3: class name
+        private final Pattern pat =
+                Pattern.compile("(?i)(<html>)?.*?(?:package ([a-z]+);.*?(?:class ([a-z]+).*)?)?");
+
+        /**
+         * Infer the file in which to write the given source.
+         * @param dir the base source directory
+         * @param src the source text
+         * @return the file in which the source should be written
+         */
+        File getSrcFile(File srcDir, String src) {
+            String f;
+            Matcher m = pat.matcher(src);
+            if (!m.matches())
+                throw new Error("match failed");
+            if (m.group(3) != null) {
+                f = m.group(2) + "/" + m.group(3) + ".java";
+            } else if (m.group(2) != null) {
+                f = m.group(2) + "/" + (m.group(1) == null ? "package-info.java" : "package.html");
+            } else {
+                f = "overview.html";
+            }
+            return new File(srcDir, f);
+        }
+
+        /**
+         * Get the options to give to javadoc.
+         * @param srcDir the srcDir to use -overview is needed
+         * @return
+         */
+        List<String> getOpts(File srcDir) {
+            if (!opts.isEmpty()) {
+                return opts;
+            } else if (sources.get(0).contains("overview")) {
+                return Arrays.asList("-overview", getSrcFile(srcDir, sources.get(0)).getPath());
+            } else {
+                return Collections.emptyList();
+            }
+        }
+
+        /**
+         * Gets the output file corresponding to the first source file.
+         * This file should not be written if the comment contains JavaScript and JavaScripot is
+         * not allowed.
+         * @param dir the base output directory
+         * @return the output file
+         */
+        File getOutFile(File outDir) {
+            String f;
+            Matcher m = pat.matcher(sources.get(0));
+            if (!m.matches())
+                throw new Error("match failed");
+            if (m.group(3) != null) {
+                f = m.group(2) + "/" + m.group(3) + ".html";
+            } else if (m.group(2) != null) {
+                f = m.group(2) + "/package-summary.html";
+            } else {
+                f = "overview-summary.html";
+            }
+            return new File(outDir, f);
+        }
+
+        final List<String> opts;
+        final List<String> sources;
+    };
+
+    enum Option {
+        OFF(null),
+        ON("--allow-script-in-comments");
+
+        Option(String text) {
+            this.text = text;
+        }
+
+        final String text;
+    };
+
+    private PrintStream out = System.err;
+
+    public void run() throws Exception {
+        int count = 0;
+        for (Template template: Template.values()) {
+            for (Comment comment: Comment.values()) {
+                for (Option option: Option.values()) {
+                    if (test(template, comment, option)) {
+                        count++;
+                    }
+                }
+            }
+        }
+
+        out.println(count + " test cases run");
+        if (errors > 0) {
+            throw new Exception(errors + " errors occurred");
+        }
+    }
+
+    boolean test(Template template, Comment comment, Option option) throws IOException {
+        if (option == Option.ON && !comment.hasScript) {
+            // skip --allowScriptInComments if comment does not contain JavaScript
+            return false;
+        }
+
+        String test = template + "-" + comment + "-" + option;
+        out.println("Test: " + test);
+
+        File dir = new File(test);
+        dir.mkdirs();
+        File srcDir = new File(dir, "src");
+        File outDir = new File(dir, "out");
+
+        String alert = "alert(\"" + test + "\");";
+        for (String src: template.sources) {
+            writeFile(template.getSrcFile(srcDir, src),
+                src.replace("#COMMENT",
+                        "/** " + comment.text.replace("#ALERT", alert) + " **/"));
+        }
+
+        List<String> opts = new ArrayList<String>();
+        opts.add("-sourcepath");
+        opts.add(srcDir.getPath());
+        opts.add("-d");
+        opts.add(outDir.getPath());
+        if (option.text != null)
+            opts.add(option.text);
+        for (String opt: template.getOpts(srcDir)) {
+            opts.add(opt.replace("#COMMENT", comment.text.replace("#ALERT", alert)));
+        }
+        opts.addAll(comment.opts);
+        opts.add("-noindex");   // index not required; save time/space writing files
+        opts.add("p");
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = javadoc(opts, pw);
+        pw.close();
+        String log = sw.toString();
+        writeFile(new File(dir, "log.txt"), log);
+
+        out.println("opts: " + opts);
+        out.println("  rc: " + rc);
+        out.println(" log:");
+        out.println(log);
+
+        String ERROR = "Use --allow-script-in-comment";
+        File outFile = template.getOutFile(outDir);
+
+        boolean expectErrors = comment.hasScript && (option == Option.OFF);
+
+        if (expectErrors) {
+            check(rc != 0, "unexpected exit code: " + rc);
+            check(log.contains(ERROR), "expected error message not found");
+            check(!outFile.exists(), "output file found unexpectedly");
+        } else {
+            check(rc == 0, "unexpected exit code: " + rc);
+            check(!log.contains(ERROR), "error message found");
+            check(outFile.exists(), "output file not found");
+        }
+
+        out.println();
+        return true;
+    }
+
+    int javadoc(List<String> opts, PrintWriter pw) {
+        return jdk.javadoc.internal.tool.Main.execute(opts.toArray(new String[opts.size()]), pw);
+    }
+
+    File writeFile(File f, String text) throws IOException {
+        f.getParentFile().mkdirs();
+        FileWriter fw = new FileWriter(f);
+        try {
+            fw.write(text);
+        } finally {
+            fw.close();
+        }
+        return f;
+    }
+
+    void check(boolean cond, String errMessage) {
+        if (!cond) {
+            error(errMessage);
+        }
+    }
+
+    void error(String message) {
+        out.println("Error: " + message);
+        errors++;
+    }
+
+    int errors = 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/treeapi/TestDocTrees.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, 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 8157611
+ * @summary test DocTrees is working correctly relative to HTML access
+ * @modules
+ *      jdk.javadoc/jdk.javadoc.internal.api
+ *      jdk.javadoc/jdk.javadoc.internal.tool
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.ToolBox toolbox.TestRunner
+ * @run main TestDocTrees
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+import toolbox.Task.Expect;
+
+import static toolbox.Task.OutputKind.*;
+
+/**
+ * This class is used to test DocTrees functionality relating to
+ * package and overview HTML files.
+ */
+public class TestDocTrees extends TestRunner {
+    final ToolBox tb;
+    final File testFile;
+    final File testSrc;
+    final File overviewFile;
+
+    TestDocTrees() throws IOException {
+        super(System.err);
+        tb = new ToolBox();
+        testSrc = new File(System.getProperty("test.src"));
+        testFile = new File(testSrc, "TestDocTrees.java");
+        overviewFile = new File(testSrc, "overview.html");
+    }
+
+    protected void runTests() throws Exception {
+        runTests(m -> new Object[]{Paths.get(m.getName())});
+    }
+
+    public static void main(String... args) throws Exception {
+        new TestDocTrees().runTests();
+    }
+
+    @Test
+    public void testOverviewWithRelease8(Path out) {
+        execTask("-d", out.toString(),
+                "--release", "8",
+                "-Xdoclint:all",
+                "-Xdoclint:-missing",
+                "-sourcepath", testSrc.getAbsolutePath(),
+                testFile.getAbsolutePath(),
+                "-overview", overviewFile.getAbsolutePath());
+    }
+
+    @Test
+    public void testOverviewWithoutRelease(Path out) throws Exception {
+        execTask("-d", out.toString(),
+                "-Xdoclint:all",
+                "-Xdoclint:-missing",
+                "-sourcepath", testSrc.getAbsolutePath(),
+                testFile.getAbsolutePath(),
+                "-overview", overviewFile.getAbsolutePath());
+    }
+
+    private Task.Result execTask(String... args) {
+        JavadocTask et = new JavadocTask(tb, Task.Mode.CMDLINE);
+        //args.forEach((a -> System.err.println("arg: " + a)));
+        return et.options(args).run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/treeapi/overview.html	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,27 @@
+<!--
+  Copyright (c) 2016, 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
+  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.
+-->
+<html>
+  <body>
+    <b>{@link omg.what.gives}</b>
+  </body>
+</html>
\ No newline at end of file
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary Testing external editor.
- * @bug 8143955 8080843 8163816 8143006 8169828
+ * @bug 8143955 8080843 8163816 8143006 8169828 8171130
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ReplToolTesting CustomEditor EditorTestBase
  * @run testng ExternalEditorTest
@@ -50,6 +50,7 @@
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 
 public class ExternalEditorTest extends EditorTestBase {
@@ -119,6 +120,28 @@
         super.testEditor(defaultStartup, args, t);
     }
 
+    @Test
+    public void testStatementSemicolonAddition() {
+        testEditor(
+                a -> assertCommand(a, "if (true) {}", ""),
+                a -> assertCommand(a, "if (true) {} else {}", ""),
+                a -> assertCommand(a, "Object o", "o ==> null"),
+                a -> assertCommand(a, "if (true) o = new Object() { int x; }", ""),
+                a -> assertCommand(a, "if (true) o = new Object() { int y; }", ""),
+                a -> assertCommand(a, "System.err.flush()", ""), // test still ; for expression statement
+                a -> assertEditOutput(a, "/ed", "", () -> {
+                    assertEquals(getSource(),
+                            "if (true) {}\n" +
+                            "if (true) {} else {}\n" +
+                            "Object o;\n" +
+                            "if (true) o = new Object() { int x; };\n" +
+                            "if (true) o = new Object() { int y; };\n" +
+                            "System.err.flush();\n");
+                    exit();
+                })
+        );
+    }
+
     private static boolean isWindows() {
         return System.getProperty("os.name").startsWith("Windows");
     }
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -23,7 +23,7 @@
 
  /*
  * @test
- * @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102
+ * @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368 8172102 8172179
  * @summary Tests of jshell comand options, and undoing operations
  * @modules jdk.jshell/jdk.internal.jshell.tool
  *          jdk.compiler/com.sun.tools.javac.api
@@ -273,14 +273,13 @@
                 (a) -> assertCommand(a, "/set start DEFAULT PRINTING",
                         ""),
                 (a) -> assertCommandOutputContains(a, "/set start",
-                        "void println", "import java.util.*"),
+                        "/set start DEFAULT PRINTING", "void println", "import java.util.*"),
                 (a) -> assertCommand(a, "/set start " + startup.toString(),
                         ""),
-                (a) -> assertCommand(a, "/set start",
-                        "|  startup.jsh:\n" +
-                        "|  int iAmHere = 1234;\n" +
-                        "|  \n" +
-                        "|  /set start startup.jsh"),
+                (a) -> assertCommandOutputContains(a, "/set start",
+                        "|  /set start " + startup + "\n" +
+                        "|  ---- " + startup + " @ ", " ----\n" +
+                        "|  int iAmHere = 1234;\n"),
                 (a) -> assertCommand(a, "/se sta -no",
                         ""),
                 (a) -> assertCommand(a, "/set start",
@@ -322,11 +321,18 @@
                         "|  /set start -retain -none"),
                 (a) -> assertCommand(a, "/set start -retain " + startup.toString(),
                         ""),
-                (a) -> assertCommand(a, "/set start",
-                        "|  startup.jsh:\n" +
-                        "|  int iAmHere = 1234;\n" +
-                        "|  \n" +
-                        "|  /set start -retain startup.jsh")
+                (a) -> assertCommand(a, "/set start DEFAULT PRINTING",
+                        ""),
+                (a) -> assertCommandOutputStartsWith(a, "/set start",
+                        "|  /set start -retain " + startup.toString() + "\n" +
+                        "|  /set start DEFAULT PRINTING\n" +
+                        "|  ---- " + startup.toString() + " @ "),
+                (a) -> assertCommandOutputContains(a, "/set start",
+                        "|  ---- DEFAULT ----\n",
+                        "|  ---- PRINTING ----\n",
+                        "|  int iAmHere = 1234;\n",
+                        "|  void println(String s)",
+                        "|  import java.io.*;")
         );
     }
 
--- a/langtools/test/jdk/jshell/ToolFormatTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969
+ * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840 8166637 8161969 8173007
  * @summary Tests for output customization
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -38,8 +38,6 @@
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import org.testng.annotations.Test;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
@@ -140,6 +138,66 @@
         );
     }
 
+    public void testSetFormatSelectorSample() {
+        test(
+                (a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
+                            "|  Created new feedback mode: ate"),
+                (a) -> assertCommand(a, "/set feedback ate", ""),
+
+                (a) -> assertCommand(a, "/set format ate display '---replaced,modified,added-primary---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++replaced,modified,added-primary+++' replaced,modified,added-primary", ""),
+                (a) -> assertCommand(a, "\"replaced,modified,added-primary\"", "+++replaced,modified,added-primary+++"),
+
+                (a) -> assertCommand(a, "/set format ate display '---added-primary,update---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++added-primary,update+++' added-primary,update", ""),
+                (a) -> assertCommand(a, "\"added-primary,update\"", "+++added-primary,update+++"),
+
+
+                (a) -> assertCommand(a, "/set format ate display '---method-replaced-primary---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++method-replaced-primary+++' method-replaced-primary", ""),
+                (a) -> assertCommand(a, "\"method-replaced-primary\"", "---method-replaced-primary---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---method-replaced-update---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++method-replaced-update+++' method-replaced-update", ""),
+                (a) -> assertCommand(a, "\"method-replaced-update\"", "---method-replaced-update---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---method-added-update---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++method-added-update+++' method-added-update", ""),
+                (a) -> assertCommand(a, "\"method-added-update\"", "---method-added-update---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---method-added---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++method-added+++' method-added", ""),
+                (a) -> assertCommand(a, "\"method-added\"", "---method-added---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---class-modified,added-primary,update---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++class-modified,added-primary,update+++' class-modified,added-primary,update", ""),
+                (a) -> assertCommand(a, "\"class-modified,added-primary,update\"", "---class-modified,added-primary,update---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---class-modified,added-primary---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++class-modified,added-primary+++' class-modified,added-primary", ""),
+                (a) -> assertCommand(a, "\"class-modified,added-primary\"", "---class-modified,added-primary---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---class-modified,added-update---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++class-modified,added-update+++' class-modified,added-update", ""),
+                (a) -> assertCommand(a, "\"class-modified,added-update\"", "---class-modified,added-update---"),
+
+                (a) -> assertCommand(a, "/set format ate display '---replaced,added---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++replaced,added+++' replaced,added", ""),
+                (a) -> assertCommand(a, "\"replaced,added\"", "+++replaced,added+++"),
+
+                (a) -> assertCommand(a, "/set format ate display '---replaced-primary,update---'", ""),
+                (a) -> assertCommand(a, "/set format ate display '+++replaced-primary,update+++' replaced-primary,update", ""),
+                (a) -> assertCommand(a, "\"replaced-primary,update\"", "---replaced-primary,update---"),
+
+                (a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "|  Feedback mode: normal")
+        );
+    }
+
+    // This test is exhaustive and takes to long for routine testing -- disabled.
+    // A sampling of these has been added (above: testSetFormatSelectorSample).
+    // See 8173007
+    // Save for possible future deep testing or debugging
+    @Test(enabled = false)
     public void testSetFormatSelector() {
         List<ReplTest> tests = new ArrayList<>();
         tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
@@ -202,6 +260,11 @@
                     tests.add((a) -> assertCommand(a, "/set format ate display '" + no  + "'", ""));
                     tests.add((a) -> assertCommand(a, "/set format ate display '" + yes + "' " + select, ""));
                     tests.add((a) -> assertCommand(a, "\"" + select + "\"", expect));
+             /**** for sample generation ****
+             System.err.println("                (a) -> assertCommand(a, \"/set format ate display '" + no  + "'\", \"\"),");
+             System.err.println("                (a) -> assertCommand(a, \"/set format ate display '" + yes + "' " + select + "\", \"\"),");
+             System.err.println("                (a) -> assertCommand(a, \"\\\"" + select + "\\\"\", \"" + expect + "\"),\n");
+             ****/
                 }
             }
         }
--- a/langtools/test/tools/doclint/html/OtherTagsTest.out	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/doclint/html/OtherTagsTest.out	Fri Jan 20 19:10:00 2017 +0000
@@ -19,10 +19,7 @@
 OtherTagsTest.java:21: error: element not allowed in documentation comments: <noframes>
      *  <noframes> </noframes>
         ^
-OtherTagsTest.java:22: error: element not allowed in documentation comments: <script>
-     *  <script> </script>
-        ^
 OtherTagsTest.java:23: error: element not allowed in documentation comments: <title>
      *  <title> </title>
         ^
-9 errors
+8 errors
--- a/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -143,6 +143,7 @@
                     Arrays.asList(new File(System.getProperty("test.src"),
                     this.getClass().getName() + ".java")));
             java.util.List<String> options = Arrays.asList(
+                "--add-modules", "jdk.jdeps",
                 "--add-exports", "jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
                 "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
                 "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
--- a/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,7 +24,7 @@
 /*
  * @test
  * @summary Module attribute tests
- * @bug 8080878 8161906 8162713
+ * @bug 8080878 8161906 8162713 8170250
  * @modules java.compiler
  *          jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -53,6 +53,28 @@
     }
 
     @Test
+    public void testOpenEmptyModule(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m", ModuleFlag.OPEN)
+                .write(base);
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
+    public void testModuleName(Path base) throws Exception {
+        testName("module.name", base.resolve("dot"));
+        testName("module.exports.component.subcomponent.more.dots", base.resolve("dots"));
+        testName("moduleName", base.resolve("noDots"));
+    }
+
+    private void testName(String name, Path path) throws Exception{
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor(name)
+                .write(path);
+        compile(path);
+        testModuleAttribute(path, moduleDescriptor);
+    }
+
+    @Test
     public void testExports(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .exports("pack")
@@ -92,16 +114,6 @@
     }
 
     @Test
-    public void testQualifiedDynamicExports(Path base) throws Exception {
-        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
-                .exportsTo("pack", "jdk.compiler")
-                .write(base);
-        tb.writeJavaFiles(base, "package pack; public class A { }");
-        compile(base);
-        testModuleAttribute(base, moduleDescriptor);
-    }
-
-    @Test
     public void testSeveralQualifiedExports(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .exportsTo("pack", "jdk.compiler, jdk.jdeps")
@@ -121,6 +133,47 @@
     }
 
     @Test
+    public void testOpens(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.name")
+                .opens("pack")
+                .write(base);
+        tb.writeJavaFiles(base, "package pack; public class C extends java.util.ArrayList{ }");
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
+    public void testQualifiedOpens(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
+                .opensTo("pack", "jdk.compiler")
+                .write(base);
+        tb.writeJavaFiles(base, "package pack; public class A { }");
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
+    public void testSeveralOpens(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.m1.name")
+                .opensTo("pack", "jdk.compiler, jdk.jdeps")
+                .opensTo("pack2", "jdk.jdeps")
+                .opensTo("pack3", "jdk.compiler")
+                .opensTo("pack4", "jdk.compiler, jdk.jdeps")
+                .opensTo("pack5", "jdk.compiler")
+                .opens("pack6")
+                .write(base);
+        tb.writeJavaFiles(base,
+                "package pack; public class A {}",
+                "package pack2; public class B {}",
+                "package pack3; public class C {}",
+                "package pack4; public class C {}",
+                "package pack5; public class C {}",
+                "package pack6; public class C {}");
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
     public void testRequires(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .requires("jdk.compiler")
@@ -182,10 +235,12 @@
                 .provides("java.util.Collection", "pack2.D")
                 .provides("java.util.List", "pack2.D")
                 .requires("jdk.compiler")
+                .provides("javax.tools.FileObject", "pack2.E")
                 .provides("com.sun.tools.javac.Main", "pack2.C")
                 .write(base);
         tb.writeJavaFiles(base, "package pack2; public class D extends java.util.ArrayList{ }",
-                "package pack2; public class C extends com.sun.tools.javac.Main{ }");
+                "package pack2; public class C extends com.sun.tools.javac.Main{ }",
+                "package pack2; public class E extends javax.tools.SimpleJavaFileObject{ public E(){ super(null,null); } }");
         compile(base);
         testModuleAttribute(base, moduleDescriptor);
     }
@@ -203,9 +258,10 @@
     public void testSeveralUses(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .uses("java.util.List")
-                .uses("java.util.Collection")
+                .uses("java.util.Collection") // from java.base
                 .requires("jdk.compiler")
-                .uses("javax.tools.JavaCompiler")
+                .uses("javax.tools.JavaCompiler") // from java.compiler
+                .uses("com.sun.tools.javac.Main") // from jdk.compiler
                 .write(base);
         compile(base);
         testModuleAttribute(base, moduleDescriptor);
@@ -216,9 +272,10 @@
         Path m1 = base.resolve("m1x");
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x")
                 .exports("pack1")
-                .exports("pack3")
+                .opens("pack3")
                 .exportsTo("packTo1", "m2x")
-                .exportsTo("packTo3", "m3x")
+                .opensTo("packTo1", "m2x") // the same as exportsTo
+                .opensTo("packTo3", "m3x")
                 .requires("jdk.compiler")
                 .requires("m2x", RequiresFlag.TRANSITIVE)
                 .requires("m3x", RequiresFlag.STATIC)
@@ -230,9 +287,49 @@
                 .requires("m5x", RequiresFlag.STATIC)
                 .requires("m6x", RequiresFlag.TRANSITIVE)
                 .requires("java.compiler")
-                .exportsTo("packTo4", "java.compiler")
+                .opensTo("packTo4", "java.compiler")
                 .exportsTo("packTo2", "java.compiler")
-                .exports("pack4")
+                .opens("pack2") // same as exports
+                .opens("pack4")
+                .exports("pack2")
+                .write(m1);
+        tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
+                "package pack2; public class D extends java.util.ArrayList{ }",
+                "package pack3; public class D extends java.util.ArrayList{ }",
+                "package pack4; public class D extends java.util.ArrayList{ }");
+        tb.writeJavaFiles(m1,
+                "package packTo1; public class T1 {}",
+                "package packTo2; public class T2 {}",
+                "package packTo3; public class T3 {}",
+                "package packTo4; public class T4 {}");
+        tb.writeJavaFiles(base.resolve("m2x"), "module m2x { }");
+        tb.writeJavaFiles(base.resolve("m3x"), "module m3x { }");
+        tb.writeJavaFiles(base.resolve("m4x"), "module m4x { }");
+        tb.writeJavaFiles(base.resolve("m5x"), "module m5x { }");
+        tb.writeJavaFiles(base.resolve("m6x"), "module m6x { }");
+        compile(base, "--module-source-path", base.toString(),
+                "-d", base.toString());
+        testModuleAttribute(m1, moduleDescriptor);
+    }
+
+    @Test
+    public void testOpenComplexModule(Path base) throws Exception {
+        Path m1 = base.resolve("m1x");
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x", ModuleFlag.OPEN)
+                .exports("pack1")
+                .exportsTo("packTo1", "m2x")
+                .requires("jdk.compiler")
+                .requires("m2x", RequiresFlag.TRANSITIVE)
+                .requires("m3x", RequiresFlag.STATIC)
+                .requires("m4x", RequiresFlag.TRANSITIVE, RequiresFlag.STATIC)
+                .provides("java.util.List", "pack1.C", "pack2.D")
+                .uses("java.util.List")
+                .uses("java.nio.file.Path")
+                .requires("jdk.jdeps", RequiresFlag.STATIC, RequiresFlag.TRANSITIVE)
+                .requires("m5x", RequiresFlag.STATIC)
+                .requires("m6x", RequiresFlag.TRANSITIVE)
+                .requires("java.compiler")
+                .exportsTo("packTo2", "java.compiler")
                 .exports("pack2")
                 .write(m1);
         tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
--- a/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTestBase.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTestBase.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,7 +25,6 @@
 import com.sun.tools.classfile.ConstantPool;
 import com.sun.tools.classfile.ConstantPoolException;
 import com.sun.tools.classfile.Module_attribute;
-import com.sun.tools.javac.util.Pair;
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -36,11 +35,11 @@
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -74,20 +73,30 @@
         ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class"));
         Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module");
         ConstantPool constantPool = classFile.constant_pool;
-
+        testModuleName(moduleDescriptor, moduleAttribute, constantPool);
+        testModuleFlags(moduleDescriptor, moduleAttribute);
         testRequires(moduleDescriptor, moduleAttribute, constantPool);
         testExports(moduleDescriptor, moduleAttribute, constantPool);
+        testOpens(moduleDescriptor, moduleAttribute, constantPool);
         testProvides(moduleDescriptor, moduleAttribute, constantPool);
         testUses(moduleDescriptor, moduleAttribute, constantPool);
     }
 
+    private void testModuleName(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
+        tr.checkEquals(constantPool.getModuleInfo(module.module_name).getName(), moduleDescriptor.name, "Unexpected module name");
+    }
+
+    private void testModuleFlags(ModuleDescriptor moduleDescriptor, Module_attribute module) {
+        tr.checkEquals(module.module_flags, moduleDescriptor.flags, "Unexpected module flags");
+    }
+
     private void testRequires(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
         tr.checkEquals(module.requires_count, moduleDescriptor.requires.size(), "Wrong amount of requires.");
 
-        List<Pair<String, Integer>> actualRequires = new ArrayList<>();
+        List<Requires> actualRequires = new ArrayList<>();
         for (Module_attribute.RequiresEntry require : module.requires) {
-            actualRequires.add(Pair.of(
-                    require.getRequires(constantPool).replace('/', '.'),
+            actualRequires.add(new Requires(
+                    require.getRequires(constantPool),
                     require.requires_flags));
         }
         tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match");
@@ -104,18 +113,36 @@
                 tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to");
                 List<String> actualTo = new ArrayList<>();
                 for (int toIdx : export.exports_to_index) {
-                    actualTo.add(constantPool.getModuleInfo(toIdx).getName().replace('/', '.'));
+                    actualTo.add(constantPool.getModuleInfo(toIdx).getName());
                 }
                 tr.checkContains(actualTo, expectedTo, "Lists of \"exports to\" don't match.");
             }
         }
     }
 
+    private void testOpens(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
+        tr.checkEquals(module.opens_count, moduleDescriptor.opens.size(), "Wrong amount of opens.");
+        for (Module_attribute.OpensEntry open : module.opens) {
+            String pkg = constantPool.getPackageInfo(open.opens_index).getName();
+            if (tr.checkTrue(moduleDescriptor.opens.containsKey(pkg), "Unexpected open " + pkg)) {
+                Open expectedOpen = moduleDescriptor.opens.get(pkg);
+                tr.checkEquals(expectedOpen.mask, open.opens_flags, "Wrong open flags");
+                List<String> expectedTo = expectedOpen.to;
+                tr.checkEquals(open.opens_to_count, expectedTo.size(), "Wrong amount of opens to");
+                List<String> actualTo = new ArrayList<>();
+                for (int toIdx : open.opens_to_index) {
+                    actualTo.add(constantPool.getModuleInfo(toIdx).getName());
+                }
+                tr.checkContains(actualTo, expectedTo, "Lists of \"opens to\" don't match.");
+            }
+        }
+    }
+
     private void testUses(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
         tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses.");
         List<String> actualUses = new ArrayList<>();
         for (int usesIdx : module.uses_index) {
-            String uses = constantPool.getClassInfo(usesIdx).getBaseName().replace('/', '.');
+            String uses = constantPool.getClassInfo(usesIdx).getBaseName();
             actualUses.add(uses);
         }
         tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match");
@@ -131,10 +158,10 @@
         tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides.");
         Map<String, List<String>> actualProvides = new HashMap<>();
         for (Module_attribute.ProvidesEntry provide : module.provides) {
-            String provides = constantPool.getClassInfo(provide.provides_index).getBaseName().replace('/', '.');
+            String provides = constantPool.getClassInfo(provide.provides_index).getBaseName();
             List<String> impls = new ArrayList<>();
             for (int i = 0; i < provide.with_count; i++) {
-                String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName().replace('/', '.');
+                String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName();
                 impls.add(with);
             }
             actualProvides.put(provides, impls);
@@ -163,9 +190,27 @@
         int getMask();
     }
 
+    public enum ModuleFlag implements Mask {
+        OPEN("open", Module_attribute.ACC_OPEN);
+
+        private final String token;
+        private final int mask;
+
+        ModuleFlag(String token, int mask) {
+            this.token = token;
+            this.mask = mask;
+        }
+
+        @Override
+        public int getMask() {
+            return mask;
+        }
+    }
+
     public enum RequiresFlag implements Mask {
         TRANSITIVE("transitive", Module_attribute.ACC_TRANSITIVE),
-        STATIC("static", Module_attribute.ACC_STATIC_PHASE);
+        STATIC("static", Module_attribute.ACC_STATIC_PHASE),
+        MANDATED("", Module_attribute.ACC_MANDATED);
 
         private final String token;
         private final int mask;
@@ -181,13 +226,30 @@
         }
     }
 
-    public enum ExportFlag implements Mask {
+    public enum ExportsFlag implements Mask {
         SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
 
         private final String token;
         private final int mask;
 
-        ExportFlag(String token, int mask) {
+        ExportsFlag(String token, int mask) {
+            this.token = token;
+            this.mask = mask;
+        }
+
+        @Override
+        public int getMask() {
+            return mask;
+        }
+    }
+
+    public enum OpensFlag implements Mask {
+        SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
+
+        private final String token;
+        private final int mask;
+
+        OpensFlag(String token, int mask) {
             this.token = token;
             this.mask = mask;
         }
@@ -199,27 +261,64 @@
     }
 
     private class Export {
-        String pkg;
-        int mask;
-        List<String> to = new ArrayList<>();
+        private final String pkg;
+        private final int mask;
+        private final List<String> to = new ArrayList<>();
 
-        public Export(String pkg, int mask) {
+        Export(String pkg, int mask) {
+            this.pkg = pkg;
+            this.mask = mask;
+        }
+    }
+
+    private class Open {
+        private final String pkg;
+        private final int mask;
+        private final List<String> to = new ArrayList<>();
+
+        Open(String pkg, int mask) {
             this.pkg = pkg;
             this.mask = mask;
         }
     }
 
+    private class Requires {
+        private final String module;
+        private final int mask;
+
+        Requires(String module, int mask) {
+            this.module = module;
+            this.mask = mask;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            Requires requires = (Requires) o;
+            return mask == requires.mask &&
+                    Objects.equals(module, requires.module);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(module, mask);
+        }
+    }
+
     protected class ModuleDescriptor {
 
         private final String name;
-        //pair is name of module and flag(public,mandated,synthetic)
-        private final List<Pair<String, Integer>> requires = new ArrayList<>();
+        private final int flags;
+
+        private final List<Requires> requires = new ArrayList<>();
 
         {
-            requires.add(new Pair<>("java.base", Module_attribute.ACC_MANDATED));
+            requires.add(new Requires("java.base", computeMask(RequiresFlag.MANDATED)));
         }
 
         private final Map<String, Export> exports = new HashMap<>();
+        private final Map<String, Open> opens = new HashMap<>();
 
         //List of service and implementation
         private final Map<String, List<String>> provides = new LinkedHashMap<>();
@@ -227,22 +326,26 @@
 
         private static final String LINE_END = ";\n";
 
-        StringBuilder content = new StringBuilder("module ");
+        StringBuilder content = new StringBuilder("");
 
-        public ModuleDescriptor(String moduleName) {
+        public ModuleDescriptor(String moduleName, ModuleFlag... flags) {
             this.name = moduleName;
-            content.append(name).append('{').append('\n');
+            this.flags = computeMask(flags);
+            for (ModuleFlag flag : flags) {
+                content.append(flag.token).append(" ");
+            }
+            content.append("module ").append(moduleName).append('{').append('\n');
         }
 
         public ModuleDescriptor requires(String module) {
-            this.requires.add(Pair.of(module, 0));
+            this.requires.add(new Requires(module, 0));
             content.append("    requires ").append(module).append(LINE_END);
 
             return this;
         }
 
         public ModuleDescriptor requires(String module, RequiresFlag... flags) {
-            this.requires.add(new Pair<>(module, computeMask(flags)));
+            this.requires.add(new Requires(module, computeMask(flags)));
 
             content.append("    requires ");
             for (RequiresFlag flag : flags) {
@@ -253,26 +356,52 @@
             return this;
         }
 
-        public ModuleDescriptor exports(String pkg, ExportFlag... flags) {
-            this.exports.putIfAbsent(pkg, new Export(pkg, computeMask(flags)));
+        public ModuleDescriptor exports(String pkg, ExportsFlag... flags) {
+            this.exports.put(toInternalForm(pkg), new Export(toInternalForm(pkg), computeMask(flags)));
             content.append("    exports ");
-            for (ExportFlag flag : flags) {
+            for (ExportsFlag flag : flags) {
                 content.append(flag.token).append(" ");
             }
             content.append(pkg).append(LINE_END);
             return this;
         }
 
-        public ModuleDescriptor exportsTo(String pkg, String to, ExportFlag... flags) {
+        public ModuleDescriptor exportsTo(String pkg, String to, ExportsFlag... flags) {
             List<String> tos = Pattern.compile(",")
                     .splitAsStream(to)
                     .map(String::trim)
                     .collect(Collectors.toList());
-            this.exports.computeIfAbsent(pkg, k -> new Export(pkg, computeMask(flags)))
+            this.exports.compute(toInternalForm(pkg), (k,v) -> new Export(k, computeMask(flags)))
                     .to.addAll(tos);
 
             content.append("    exports ");
-            for (ExportFlag flag : flags) {
+            for (ExportsFlag flag : flags) {
+                content.append(flag.token).append(" ");
+            }
+            content.append(pkg).append(" to ").append(to).append(LINE_END);
+            return this;
+        }
+
+        public ModuleDescriptor opens(String pkg, OpensFlag... flags) {
+            this.opens.put(toInternalForm(pkg), new Open(toInternalForm(pkg), computeMask(flags)));
+            content.append("    opens ");
+            for (OpensFlag flag : flags) {
+                content.append(flag.token).append(" ");
+            }
+            content.append(pkg).append(LINE_END);
+            return this;
+        }
+
+        public ModuleDescriptor opensTo(String pkg, String to, OpensFlag... flags) {
+            List<String> tos = Pattern.compile(",")
+                    .splitAsStream(to)
+                    .map(String::trim)
+                    .collect(Collectors.toList());
+            this.opens.compute(toInternalForm(pkg), (k,v) -> new Open(toInternalForm(k), computeMask(flags)))
+                    .to.addAll(tos);
+
+            content.append("    opens ");
+            for (OpensFlag flag : flags) {
                 content.append(flag.token).append(" ");
             }
             content.append(pkg).append(" to ").append(to).append(LINE_END);
@@ -280,7 +409,10 @@
         }
 
         public ModuleDescriptor provides(String provides, String... with) {
-            this.provides.put(provides, Arrays.asList(with));
+            List<String> impls = Arrays.stream(with)
+                    .map(this::toInternalForm)
+                    .collect(Collectors.toList());
+            this.provides.put(toInternalForm(provides), impls);
             content.append("    provides ")
                     .append(provides)
                     .append(" with ")
@@ -290,8 +422,8 @@
         }
 
         public ModuleDescriptor uses(String... uses) {
-            Collections.addAll(this.uses, uses);
             for (String use : uses) {
+                this.uses.add(toInternalForm(use));
                 content.append("    uses ").append(use).append(LINE_END);
             }
             return this;
@@ -305,7 +437,11 @@
             return this;
         }
 
-        private int computeMask(Mask[] masks) {
+        private String toInternalForm(String name) {
+            return name.replace('.', '/');
+        }
+
+        private int computeMask(Mask... masks) {
             return Arrays.stream(masks)
                     .map(Mask::getMask)
                     .reduce((a, b) -> a | b)
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -82,7 +82,8 @@
         Set<?> copy = new HashSet<>(expected);
         copy.removeAll(found);
         if (!found.containsAll(expected)) {
-            return checkTrue(false, message + " FAIL : not found elements : " + copy);
+            return checkTrue(false, message + " FAIL : not found elements : " + copy + "\n" +
+                    "Actual: " + found);
         } else {
             return checkTrue(true, message + " PASS : all elements found");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classreader/FileSystemClosedTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2016, 2017, 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 8147414
+ * @summary java.nio.file.ClosedFileSystemException in javadoc
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.JarTask toolbox.JavacTask toolbox.ToolBox
+ * @run main FileSystemClosedTest
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.ClosedFileSystemException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import toolbox.ToolBox;
+import toolbox.JarTask;
+import toolbox.JavacTask;
+
+public class FileSystemClosedTest {
+    public static void main(String... args) throws Exception {
+        new FileSystemClosedTest().run();
+    }
+
+    void run() throws Exception {
+        ToolBox tb = new ToolBox();
+        Path jar = createJar(tb);
+
+        Path src = Paths.get("src");
+        tb.writeJavaFiles(src, "class C { p1.C1 c1; }");
+
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        PrintWriter out = new PrintWriter(System.err, true);
+        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+        List<String> options = Arrays.asList("-classpath", jar.toString());
+        Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(src.resolve("C.java"));
+        com.sun.source.util.JavacTask task =
+                (com.sun.source.util.JavacTask) comp.getTask(out, fm, null, options, null, files);
+        task.parse();
+
+        Elements elems = task.getElements();
+
+        try {
+            // Use  p1, p1.C1 as a control to verify normal behavior
+            PackageElement p1 = elems.getPackageElement("p1");
+            TypeElement p1C1 = elems.getTypeElement("p1.C1");
+            System.err.println("p1: " + p1 + ";  p1C1: " + p1C1);
+            if (p1C1 == null) {
+                throw new Exception("p1.C1 not found");
+            }
+
+            // Now repeat for p2, p2.C2, closing the file manager early
+            PackageElement p2 = elems.getPackageElement("p2");
+            System.err.println("closing file manager");
+            fm.close();
+            TypeElement p2C2 = elems.getTypeElement("p2.C2");
+            System.err.println("p2: " + p2 + ";  p2C2: " + p2C2);
+            if (p2C2 != null) {
+                throw new Exception("p1.C1 found unexpectedly");
+            }
+        } catch (ClosedFileSystemException e) {
+            throw new Exception("unexpected exception thrown", e);
+        }
+
+    }
+
+    private Path createJar(ToolBox tb) throws IOException {
+        Path jarSrc = Paths.get("jarSrc");
+        Path jarClasses = Paths.get("jarClasses");
+        Path jar = Paths.get("jar.jar");
+        Files.createDirectories(jarClasses);
+
+        tb.writeJavaFiles(jarSrc,
+                "package p1; public class C1 { }",
+                "package p2; public class C2 { }");
+
+        new JavacTask(tb)
+                .outdir(jarClasses)
+                .files(tb.findJavaFiles(jarSrc))
+                .run()
+                .writeAll();
+        new JarTask(tb)
+                .run("cf", jar.toString(), "-C", jarClasses.toString(), "p1", "p2");
+
+        return jar;
+    }
+}
+
--- a/langtools/test/tools/javac/diags/Example.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/Example.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -66,6 +66,7 @@
         modulePathFiles = new ArrayList<File>();
         classPathFiles = new ArrayList<File>();
         additionalFiles = new ArrayList<File>();
+        nonEmptySrcFiles = new ArrayList<File>();
 
         findFiles(file, srcFiles);
         for (File f: srcFiles) {
@@ -99,11 +100,11 @@
                 }
             }
         } else if (f.isFile()) {
-                if (f.getName().endsWith(".java")) {
-                    files.add(f);
-                } else if (f.getName().equals("modulesourcepath")) {
-                    moduleSourcePathDir = f;
-                }
+            if (f.getName().endsWith(".java")) {
+                files.add(f);
+            } else if (f.getName().equals("modulesourcepath")) {
+                moduleSourcePathDir = f;
+            }
         }
     }
 
@@ -132,8 +133,10 @@
                     foundInfo(f);
                     runOpts = Arrays.asList(runMatch.group(1).trim().split(" +"));
                 }
-                if (javaPat.matcher(line).matches())
+                if (javaPat.matcher(line).matches()) {
+                    nonEmptySrcFiles.add(f);
                     break;
+                }
             }
         } catch (IOException e) {
             throw new Error(e);
@@ -236,6 +239,7 @@
             // source for import statements or a magic comment
             for (File pf: procFiles) {
                 if (pf.getName().equals("CreateBadClassFile.java")) {
+                    pOpts.add("--add-modules=jdk.jdeps");
                     pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED");
                 }
             }
@@ -263,7 +267,9 @@
         if (moduleSourcePathDir != null) {
             opts.add("--module-source-path");
             opts.add(moduleSourcePathDir.getPath());
-            files = moduleSourcePathFiles;
+            files = new ArrayList<>();
+            files.addAll(moduleSourcePathFiles);
+            files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
         }
 
         if (additionalFiles.size() > 0) {
@@ -343,6 +349,7 @@
     List<File> modulePathFiles;
     List<File> classPathFiles;
     List<File> additionalFiles;
+    List<File> nonEmptySrcFiles;
     File infoFile;
     private List<String> runOpts;
     private List<String> options;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Fri Jan 20 19:10:00 2017 +0000
@@ -103,6 +103,7 @@
 compiler.warn.big.major.version                         # ClassReader
 compiler.warn.future.attr                               # ClassReader
 compiler.warn.illegal.char.for.encoding
+compiler.warn.incubating.modules                        # requires adjusted classfile
 compiler.warn.invalid.archive.file
 compiler.warn.override.bridge
 compiler.warn.position.overflow                         # CRTable: caused by files with long lines >= 1024 chars
--- a/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/DirPathElementNotDirectory.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/DirPathElementNotDirectory/DirPathElementNotDirectory.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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,5 +24,3 @@
 // key: compiler.warn.dir.path.element.not.directory
 // options: -Xlint:path
 // run: simple
-
-class DirPathElementNotDirectory { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleNotOnModuleSourcePath/ModuleNotOnModuleSourcePath.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.module.not.found.on.module.source.path
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleNotOnModuleSourcePath/modulesourcepath/m/extra/module-info.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+module m { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotInModuleOnModuleSourcePath/NotInModuleOnModuleSourcePath.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.not.in.module.on.module.source.path
+
+package p; class C { }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotInModuleOnModuleSourcePath/modulesourcepath/m/module-info.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+module m { }
+
--- a/langtools/test/tools/javac/diags/examples/UnnamedPackageInNamedModule/UnnamedPackageInNamedModule.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/UnnamedPackageInNamedModule/UnnamedPackageInNamedModule.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -22,5 +22,3 @@
  */
 
 // key: compiler.err.unnamed.pkg.not.allowed.named.modules
-
-class UnnamedPackageInNamedModule {}
--- a/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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 @@
 
 /*
  * @test
- * @bug  8132096
+ * @bug  8132096 8157611
  * @summary test the APIs  in the DocTree interface
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
@@ -48,12 +48,15 @@
 import java.util.Locale;
 
 import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.util.Elements;
 import javax.tools.FileObject;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 
 import com.sun.source.doctree.DocTree;
 import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.util.DocTreePath;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.api.JavacTool;
@@ -90,6 +93,9 @@
             // tests files relative path in an unnamed package
             test.runRelativePathTest("OverviewTest.java", "overview0.html");
 
+            // tests doctreepath using package element and package.html
+            test.runDocTreePath("pkg/Anchor.java", "package.html");
+
             // test for correct parsing using valid and some invalid html tags
             for (int i = 0; i < 7; i++) {
                 String hname = "overview" + i + ".html";
@@ -152,6 +158,7 @@
             }
         }
     }
+
     /**
      * Tests DocTrees.getDocCommentTree(Element e, String relpath) using relative path.
      *
@@ -219,6 +226,49 @@
         }
     }
 
+    /**
+     * Tests DocTrees.getDocTreePath(PackageElement p, FileObject fo).
+     *
+     * @param javaFileName the java anchor file
+     * @param pkgFileName the package file name
+     * @throws Exception e if something goes awry
+     */
+    public void runDocTreePath(String javaFileName, String pkgFileName) throws Exception  {
+        List<File> javaFiles = new ArrayList<>();
+        javaFiles.add(new File(testSrc, javaFileName));
+
+        List<File> dirs = new ArrayList<>();
+        dirs.add(new File(testSrc));
+
+        try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
+            fm.setLocation(javax.tools.StandardLocation.SOURCE_PATH, dirs);
+            Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
+
+            final JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+            final DocTrees trees = DocTrees.instance(t);
+            final Elements elementUtils = t.getElements();
+
+            Iterable<? extends Element> elements = t.analyze();
+
+            Element klass = elements.iterator().next();
+            PackageElement pkg = elementUtils.getPackageOf(klass);
+
+            FileObject htmlFo = fm.getFileForInput(javax.tools.StandardLocation.SOURCE_PATH,
+                    t.getElements().getPackageOf(klass).getQualifiedName().toString(),
+                    "package.html");
+            System.out.println();
+            DocTreePath treePath = trees.getDocTreePath(htmlFo, pkg);
+            DocCommentTree dcTree = treePath.getDocComment();
+
+            StringWriter sw = new StringWriter();
+            printer.print(dcTree, sw);
+            String found = sw.toString();
+
+            String expected = getExpected(htmlFo.openReader(true));
+            astcheck(pkgFileName, expected, found);
+        }
+    }
+
     void astcheck(String testinfo, String expected, String found) {
         System.err.print("ASTChecker: " + testinfo);
         check0(expected, found);
--- a/langtools/test/tools/javac/lib/combo/ReusableContext.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/lib/combo/ReusableContext.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -38,6 +38,7 @@
 import com.sun.tools.javac.code.Type.ClassType;
 import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.comp.Check;
 import com.sun.tools.javac.comp.CompileStates;
 import com.sun.tools.javac.comp.Enter;
@@ -95,6 +96,7 @@
             Types.instance(this).newRound();
             Check.instance(this).newRound();
             Modules.instance(this).newRound();
+            Annotate.instance(this).newRound();
             CompileStates.instance(this).clear();
             MultiTaskListener.instance(this).clear();
 
--- a/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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,11 +23,12 @@
 
 /*
  * @test
- * @bug 8169197 8172668
+ * @bug 8169197 8172668 8173117
  * @summary Check convenient errors are produced for inaccessible classes.
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.javac.util
  * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
  * @run main ConvenientAccessErrorsTest
  */
@@ -37,6 +38,10 @@
 import java.util.Arrays;
 import java.util.List;
 
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Convert;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
 import toolbox.JarTask;
 import toolbox.JavacTask;
 import toolbox.Task;
@@ -79,6 +84,37 @@
     }
 
     @Test
+    public void testNoDepNested(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "module m1x { exports api; }",
+                          "package api; public class Api { public static class Nested {} }");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { }",
+                          "package test; public class Test { api.Api.Nested nested; }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--module-source-path", src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "Test.java:1:35: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m2x, api, m1x)",
+                "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found; actual: " + log);
+    }
+
+    @Test
     public void testNotExported(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1x");
@@ -390,8 +426,7 @@
 
         List<String> expected = Arrays.asList(
                 "Test.java:1:22: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.not.exported: api, m1x)",
-                "Test.java:1:49: compiler.err.not.def.access.package.cant.access: api.Api, api, (compiler.misc.not.def.access.not.exported: api, m1x)",
-                "2 errors");
+                "1 error");
 
         if (!expected.equals(log))
             throw new Exception("expected output not found; actual: " + log);
@@ -593,4 +628,80 @@
             throw new Exception("expected output not found; actual: " + log);
     }
 
+    @Test
+    public void testInaccessibleInSourceModuleViaBinaryModule(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "@Deprecated module m1x { }");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { requires transitive m1x; }");
+        Path src_m3 = src.resolve("m3x");
+        tb.writeJavaFiles(src_m3,
+                          "module m3x { requires transitive m2x; exports api; }",
+                          "package api; class Api { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        new JavacTask(tb)
+            .options("-XDrawDiagnostics",
+                     "--module-source-path", src.toString())
+            .outdir(classes)
+            .files(findJavaFiles(src))
+            .run()
+            .writeAll();
+
+        tb.cleanDirectory(classes.resolve("m2x")); //force completion from source if needed
+        Files.delete(classes.resolve("m2x"));
+
+        tb.cleanDirectory(src_m3); //binary only module
+        Files.delete(src_m3);
+
+        //m4x does not depend on m1x/m2x/m3x, so cannot access api.Api
+        //but the recovery search should not complete m2x, as that would cause a deprecation warning:
+        Path src_m4 = src.resolve("m4x");
+        tb.writeJavaFiles(src_m4,
+                          "module m4x { }",
+                          "package m4x; public class Test extends api.Api { }");
+
+        List<String> log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--module-source-path", src.toString(),
+                         "--module-path", classes.toString(),
+                         "-Xlint:deprecation")
+                .outdir(classes)
+                .files(findJavaFiles(src_m4))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "Test.java:1:40: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m4x, api, m3x)",
+                "1 error");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found; actual: " + log);
+    }
+
+    @Test
+    public void testConvertNameCandidates(Path base) throws Exception {
+        Context ctx = new Context();
+        Names names = Names.instance(ctx);
+        Name name = names.fromString("com.sun.tools.javac.Attr.BreakAttr");
+
+        com.sun.tools.javac.util.List<String> actual =
+                Convert.classCandidates(name).map(n -> n.toString());
+        List<String> expected = Arrays.asList(
+                "com.sun$tools$javac$Attr$BreakAttr",
+                "com.sun.tools$javac$Attr$BreakAttr",
+                "com.sun.tools.javac$Attr$BreakAttr",
+                "com.sun.tools.javac.Attr$BreakAttr",
+                "com.sun.tools.javac.Attr.BreakAttr"
+        );
+
+        if (!expected.equals(actual)) {
+            throw new Exception("Expected names not generated: " + actual);
+        }
+    }
 }
--- a/langtools/test/tools/javac/modules/EdgeCases.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/EdgeCases.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,13 +23,14 @@
 
 /*
  * @test
- * @bug 8154283 8167320
+ * @bug 8154283 8167320 8171098 8172809 8173117
  * @summary tests for multi-module mode compilation
  * @library /tools/lib
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.code
  *      jdk.compiler/com.sun.tools.javac.main
+ *      jdk.compiler/com.sun.tools.javac.util
  * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
  * @run main EdgeCases
  */
@@ -44,7 +45,16 @@
 import java.util.Objects;
 import java.util.Set;
 
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedOptions;
+import javax.lang.model.SourceVersion;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
@@ -484,4 +494,164 @@
             throw new AssertionError("Unexpected output: " + log);
         }
     }
+
+    @Test
+    public void testInvisibleClassVisiblePackageClash(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "module m1x { }",
+                          "package m1x;\n" +
+                          "import m1x.a.*; public class Test { A a; }\n",
+                          "package m1x.a;\n" +
+                          "public class A { }\n");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { }",
+                          "package m1x;\n" +
+                          "public class a { public static class A { } }\n");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        new JavacTask(tb)
+            .options("--module-source-path", src.toString(),
+                     "-XDrawDiagnostics")
+            .outdir(classes)
+            .files(findJavaFiles(src))
+            .run()
+            .writeAll();
+    }
+
+    @Test
+    public void testStripUnknownRequired(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "module m1x { }");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { }");
+        Path src_m3 = src.resolve("m3x");
+        tb.writeJavaFiles(src_m3,
+                          "module m3x { }");
+        Path src_m4 = src.resolve("m4x");
+        tb.writeJavaFiles(src_m4,
+                          "module m4x { }");
+        Path src_test = src.resolve("test");
+        tb.writeJavaFiles(src_test,
+                          "module test { requires m1x; requires m2x; requires java.base; requires m3x; requires m4x; }");
+        Path src_compile = src.resolve("compile");
+        tb.writeJavaFiles(src_compile,
+                          "module compile { exports p to test; }",
+                          "package p; public class Test { }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("-processor", ListRequires.class.getName(),
+                         "--module-source-path", src.toString(),
+                         "--limit-modules", "compile",
+                         "-XDaccessInternalAPI=true")
+                .outdir(classes)
+                .files(findJavaFiles(src_compile))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.STDOUT);
+
+        List<String> expected = Arrays.asList(
+                "from directives:",
+                "java.base",
+                "from requires:",
+                "java.base"
+        );
+        if (!Objects.equals(log, expected))
+            throw new AssertionError("Unexpected output: " + log);
+    }
+
+    @SupportedAnnotationTypes("*")
+    @SupportedOptions("expectedEnclosedElements")
+    public static final class ListRequires extends AbstractProcessor {
+
+        private int round;
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            if (round++ == 0) {
+                ModuleElement compileE = processingEnv.getElementUtils().getModuleElement("compile");
+                ModuleElement testE = ElementFilter.exportsIn(compileE.getDirectives()).get(0).getTargetModules().get(0);
+
+                System.out.println("from directives:");
+                for (RequiresDirective rd : ElementFilter.requiresIn(testE.getDirectives())) {
+                    System.out.println(rd.getDependency().getSimpleName());
+                }
+
+                System.out.println("from requires:");
+                for (RequiresDirective rd : ((ModuleSymbol) testE).requires) {
+                    System.out.println(rd.getDependency().getSimpleName());
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        public SourceVersion getSupportedSourceVersion() {
+            return SourceVersion.latest();
+        }
+
+    }
+
+    @Test
+    public void testOnDemandCompletionModuleInfoJava(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_m1 = src.resolve("m1x");
+        tb.writeJavaFiles(src_m1,
+                          "@Deprecated module m1x { }");
+        Path src_m2 = src.resolve("m2x");
+        tb.writeJavaFiles(src_m2,
+                          "module m2x { requires m1x; }");
+        Path src_m3 = src.resolve("m3x");
+        tb.writeJavaFiles(src_m3,
+                          "module m3x { requires m2x; requires m1x; }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log;
+        List<String> expected;
+
+        log = new JavacTask(tb)
+                .options("--module-source-path", src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src_m1))
+                .run()
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList("");
+
+        if (!expected.equals(log)) {
+            throw new IllegalStateException(log.toString());
+        }
+
+        log = new JavacTask(tb)
+                .options("--module-source-path", src.toString(),
+                         "-XDrawDiagnostics",
+                         "-Xlint:deprecation")
+                .outdir(classes)
+                .files(findJavaFiles(src_m3))
+                .run()
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList(
+                "module-info.java:1:23: compiler.warn.has.been.deprecated.module: m1x",
+                "module-info.java:1:37: compiler.warn.has.been.deprecated.module: m1x",
+                "2 warnings"
+        );
+
+        if (!expected.equals(log)) {
+            throw new IllegalStateException(log.toString());
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/IncubatingTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2015, 2017, 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 8171177
+ * @summary Verify that ModuleResolution attribute flags are honored.
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.jdeps/com.sun.tools.classfile
+ *          jdk.jdeps/com.sun.tools.javap
+ * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavapTask ModuleTestBase
+ * @run main IncubatingTest
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.Attributes;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ClassWriter;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
+import com.sun.tools.classfile.ConstantPool.CPInfo;
+import com.sun.tools.classfile.ModuleResolution_attribute;
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.Task.Expect;
+
+public class IncubatingTest extends ModuleTestBase {
+
+    public static void main(String... args) throws Exception {
+        new IncubatingTest().runTests();
+    }
+
+    @Test
+    public void testDoNotResolve(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "module jdk.i { exports api; }",
+                          "package api; public class Api { }");
+        Path classes = base.resolve("classes");
+        Files.deleteIfExists(classes);
+        Path iClasses = classes.resolve("jdk.i");
+        tb.createDirectories(iClasses);
+
+        new JavacTask(tb)
+                .outdir(iClasses)
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll();
+
+        copyJavaBase(classes);
+
+        Path jdkIModuleInfo = iClasses.resolve("module-info.class");
+        addModuleResolutionAttribute(jdkIModuleInfo, ModuleResolution_attribute.DO_NOT_RESOLVE_BY_DEFAULT);
+
+        Path testSrc = base.resolve("test-src");
+        tb.writeJavaFiles(testSrc,
+                          "class T { api.Api api; }");
+        Path testClasses = base.resolve("test-classes");
+        tb.createDirectories(testClasses);
+
+        List<String> log;
+        List<String> expected;
+
+        log = new JavacTask(tb)
+                .options("--system", "none",
+                         "--upgrade-module-path", classes.toString(),
+                         "-XDrawDiagnostics")
+                .outdir(testClasses)
+                .files(findJavaFiles(testSrc))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList(
+                "T.java:1:11: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read.from.unnamed: api, jdk.i)",
+                "1 error"
+        );
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+
+        log = new JavacTask(tb)
+                .options("--system", "none",
+                         "--upgrade-module-path", classes.toString(),
+                         "--add-modules", "ALL-SYSTEM",
+                         "-XDrawDiagnostics")
+                .outdir(testClasses)
+                .files(findJavaFiles(testSrc))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList(
+                "T.java:1:11: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read.from.unnamed: api, jdk.i)",
+                "1 error"
+        );
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+
+        new JavacTask(tb)
+                .options("--system", "none",
+                         "--upgrade-module-path", classes.toString(),
+                         "--add-modules", "jdk.i")
+                .outdir(testClasses)
+                .files(findJavaFiles(testSrc))
+                .run()
+                .writeAll();
+
+        Path testModuleSrc = base.resolve("test-module-src");
+        tb.writeJavaFiles(testModuleSrc,
+                          "module test { requires jdk.i; }", //explicit requires of an incubating module
+                          "class T { api.Api api; }");
+        Path testModuleClasses = base.resolve("test-module-classes");
+        tb.createDirectories(testModuleClasses);
+
+        new JavacTask(tb)
+                .options("--system", "none",
+                         "--upgrade-module-path", classes.toString())
+                .outdir(testModuleClasses)
+                .files(findJavaFiles(testModuleSrc))
+                .run()
+                .writeAll();
+    }
+
+    @Test
+    public void testIncubating(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "module jdk.i { exports api; }",
+                          "package api; public class Api { }");
+        Path classes = base.resolve("classes");
+        Files.deleteIfExists(classes);
+        Path iClasses = classes.resolve("jdk.i");
+        tb.createDirectories(iClasses);
+
+        new JavacTask(tb)
+                .outdir(iClasses)
+                .files(findJavaFiles(src))
+                .run()
+                .writeAll();
+
+        Path jdkIModuleInfo = iClasses.resolve("module-info.class");
+        addModuleResolutionAttribute(jdkIModuleInfo, ModuleResolution_attribute.WARN_INCUBATING);
+
+        Path testSrc = base.resolve("test-src");
+        tb.writeJavaFiles(testSrc,
+                          "class T { api.Api api; }");
+        Path testClasses = base.resolve("test-classes");
+        tb.createDirectories(testClasses);
+
+        List<String> log;
+        List<String> expected;
+
+        log = new JavacTask(tb)
+                .options("--module-path", classes.toString(),
+                         "--add-modules", "jdk.i",
+                         "-XDrawDiagnostics",
+                         "-Werror")
+                .outdir(testClasses)
+                .files(findJavaFiles(testSrc))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList(
+                "- compiler.warn.incubating.modules: jdk.i",
+                "- compiler.err.warnings.and.werror",
+                "1 error",
+                "1 warning"
+        );
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+
+        Path testModuleSrc = base.resolve("test-module-src");
+        tb.writeJavaFiles(testModuleSrc,
+                          "module test { requires jdk.i; }", //explicit requires of an incubating module
+                          "class T { api.Api api; }");
+        Path testModuleClasses = base.resolve("test-module-classes");
+        tb.createDirectories(testModuleClasses);
+
+        log = new JavacTask(tb)
+                .options("--module-path", classes.toString(),
+                         "-XDrawDiagnostics",
+                         "-Werror")
+                .outdir(testModuleClasses)
+                .files(findJavaFiles(testModuleSrc))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        expected = Arrays.asList(
+                "- compiler.warn.incubating.modules: jdk.i",
+                "- compiler.err.warnings.and.werror",
+                "1 error",
+                "1 warning"
+        );
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
+    private void copyJavaBase(Path targetDir) throws IOException {
+        FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
+        Path javaBase = jrt.getPath("modules", "java.base");
+
+        if (!Files.exists(javaBase)) {
+            throw new AssertionError("No java.base?");
+        }
+
+        Path javaBaseClasses = targetDir.resolve("java.base");
+
+        for (Path clazz : tb.findFiles("class", javaBase)) {
+            Path target = javaBaseClasses.resolve(javaBase.relativize(clazz).toString());
+            Files.createDirectories(target.getParent());
+            Files.copy(clazz, target);
+        }
+    }
+
+    private void addModuleResolutionAttribute(Path classfile, int resolution_flags) throws Exception {
+        ClassFile cf = ClassFile.read(classfile);
+        Attributes attrs = cf.attributes;
+        List<CPInfo> cpData = new ArrayList<>();
+        cpData.add(null);
+        for (CPInfo info : cf.constant_pool.entries()) {
+            cpData.add(info);
+            if (info.size() == 2)
+                cpData.add(null);
+        }
+        cpData.add(new CONSTANT_Utf8_info(Attribute.ModuleResolution));
+        ConstantPool newCP = new ConstantPool(cpData.toArray(new CPInfo[0]));
+        ModuleResolution_attribute res = new ModuleResolution_attribute(newCP, resolution_flags);
+        Map<String, Attribute> newAttributeMap = new HashMap<>(attrs.map);
+        newAttributeMap.put(Attribute.ModuleResolution, res);
+        Attributes newAttrs = new Attributes(newAttributeMap);
+        ClassFile newCF = new ClassFile(cf.magic,
+                                        cf.minor_version,
+                                        cf.major_version,
+                                        newCP,
+                                        cf.access_flags,
+                                        cf.this_class,
+                                        cf.super_class,
+                                        cf.interfaces,
+                                        cf.fields,
+                                        cf.methods,
+                                        newAttrs);
+        try (OutputStream out = Files.newOutputStream(classfile)) {
+            new ClassWriter().write(newCF, out);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 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 8165102
+ * @summary incorrect message from javac
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @run main ModulesAndModuleSourcePathTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.ToolBox;
+
+public class ModulesAndModuleSourcePathTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        ModulesAndModuleSourcePathTest t = new ModulesAndModuleSourcePathTest();
+        t.runTests();
+    }
+
+    @Test
+    public void testModuleNotInModuleSrcPath(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path m = src.resolve("m");
+        Path extra = m.resolve("extra");
+        tb.writeJavaFiles(extra, "module m {}");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics", "--module-source-path", src.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        if (!log.contains("module-info.java:1:1: compiler.err.module.not.found.on.module.source.path"))
+            throw new Exception("expected output not found");
+    }
+}
--- a/langtools/test/tools/javac/modules/MultiModuleModeTest.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/MultiModuleModeTest.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -90,7 +90,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("C.java:1:1: compiler.err.unnamed.pkg.not.allowed.named.modules"))
+        if (!log.contains("C.java:1:1: compiler.err.not.in.module.on.module.source.path"))
             throw new Exception("expected output not found");
     }
 
--- a/langtools/test/tools/javac/modules/PackageMultipleModules.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/modules/PackageMultipleModules.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -70,9 +70,10 @@
                 .writeAll()
                 .getOutputLines(Task.OutputKind.DIRECT);
 
-        List<String> expected = Arrays.asList("A.java:1:22: compiler.err.package.not.visible: test, (compiler.misc.not.def.access.does.not.read: m1x, test, m2x)",
-                                              "B.java:1:22: compiler.err.package.not.visible: test, (compiler.misc.not.def.access.does.not.read: m2x, test, m1x)",
-                                              "2 errors");
+        List<String> expected = Arrays.asList(
+                "A.java:1:26: compiler.err.cant.resolve.location: kindname.class, B, , , (compiler.misc.location: kindname.package, test, null)",
+                "B.java:1:26: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.package, test, null)",
+                "2 errors");
         if (!log.equals(expected))
             throw new Exception("expected output not found");
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/TestVisitorDefaults.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2017, 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 8172910
+ * @summary Test behavior of default methods on visitors.
+ * @modules java.compiler
+ */
+
+import java.util.List;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+/**
+ * Verify expected behavior of default methods on visitors.
+ */
+public class TestVisitorDefaults {
+    public static void main(String... args) {
+        DirectElementVisitorChild dvc = new DirectElementVisitorChild();
+        if (!"visitUnknown".equals(dvc.visitModule(null, null))) {
+            throw new RuntimeException("Problem with DirectElementVisitorChild");
+        }
+        if (!"visit".equals(dvc.visit(null))) {
+            throw new RuntimeException("Problem with DirectElementVisitorChild");
+        }
+
+        IndirectElementVisitorChild ivc = new IndirectElementVisitorChild();
+        if (!"visitUnknown".equals(ivc.visitModule(null, null))) {
+            throw new RuntimeException("Problem with IndirectElementVisitorChild");
+        }
+
+        DirectTypeVisitorChild dtvc = new DirectTypeVisitorChild();
+        if (!"visit".equals(dtvc.visit(null))) {
+            throw new RuntimeException("Problem with DirectTypeVisitorChild");
+        }
+
+        DirectAnnotationVisitorChild davc = new DirectAnnotationVisitorChild();
+        if (!"visit".equals(davc.visit(null))) {
+            throw new RuntimeException("Problem with DirectAnnotationVisitorChild");
+        }
+    }
+
+    private static class DirectElementVisitorChild
+        implements ElementVisitor<String, Object> {
+
+        public DirectElementVisitorChild() {
+            super();
+        }
+
+        @Override
+        public String visitModule(ModuleElement e, Object o) {
+            return ElementVisitor.super.visitModule(e, null);
+        }
+
+        @Override
+        public String visitUnknown(Element e, Object o) {
+            return "visitUnknown";
+        }
+
+        @Override
+        public String visit(Element e) {
+            return ElementVisitor.super.visit(e);
+        }
+
+        @Override
+        public String visit(Element e, Object o) {
+            return "visit";
+        }
+
+        @Override
+        public String visitExecutable(ExecutableElement e, Object o)       { return throwUOE(); }
+        @Override
+        public String visitPackage(PackageElement e, Object o)             { return throwUOE(); }
+        @Override
+        public String visitType(TypeElement e, Object o)                   { return throwUOE(); }
+        @Override
+        public String visitTypeParameter(TypeParameterElement e, Object o) { return throwUOE(); }
+        @Override
+        public String visitVariable(VariableElement e, Object o)           { return throwUOE(); }
+    }
+
+    private static class IndirectElementVisitorChild
+        extends AbstractElementVisitor6<String, Object> {
+
+        public IndirectElementVisitorChild() {
+            super();
+        }
+
+        @Override
+        public String visitModule(ModuleElement e, Object o) {
+            return super.visitModule(e, o);
+        }
+
+
+        @Override
+        public String visitUnknown(Element e, Object o) {
+            return "visitUnknown";
+        }
+
+        @Override
+        public String visitExecutable(ExecutableElement e, Object o)       { return throwUOE(); }
+        @Override
+        public String visitPackage(PackageElement e, Object o)             { return throwUOE(); }
+        @Override
+        public String visitType(TypeElement e, Object o)                   { return throwUOE(); }
+        @Override
+        public String visitTypeParameter(TypeParameterElement e, Object o) { return throwUOE(); }
+        @Override
+        public String visitVariable(VariableElement e, Object o)           { return throwUOE(); }
+    }
+
+
+    private static class DirectTypeVisitorChild
+        implements TypeVisitor<String, Object> {
+
+        public DirectTypeVisitorChild() {
+            super();
+        }
+
+        @Override
+        public String visit(TypeMirror t) {
+            return TypeVisitor.super.visit(t);
+        }
+
+        @Override
+        public String visit(TypeMirror t, Object o) {
+            return "visit";
+        }
+
+        @Override
+        public String visitUnknown(TypeMirror t, Object o)            { return throwUOE(); }
+        @Override
+        public String visitArray(ArrayType t, Object o)               { return throwUOE(); }
+        @Override
+        public String visitDeclared(DeclaredType t, Object o)         { return throwUOE(); }
+        @Override
+        public String visitError(ErrorType t, Object o)               { return throwUOE(); }
+        @Override
+        public String visitExecutable(ExecutableType t, Object o)     { return throwUOE(); }
+        @Override
+        public String visitIntersection(IntersectionType t, Object o) { return throwUOE(); }
+        @Override
+        public String visitNoType(NoType t, Object o)                 { return throwUOE(); }
+        @Override
+        public String visitNull(NullType t, Object o)                 { return throwUOE(); }
+        @Override
+        public String visitPrimitive(PrimitiveType t, Object o)       { return throwUOE(); }
+        @Override
+        public String visitTypeVariable(TypeVariable t, Object o)     { return throwUOE(); }
+        @Override
+        public String visitUnion(UnionType t, Object o)               { return throwUOE(); }
+        @Override
+        public String visitWildcard(WildcardType t, Object o)         { return throwUOE(); }
+    }
+
+    private static class DirectAnnotationVisitorChild
+        implements AnnotationValueVisitor<String, Object> {
+
+        @Override
+        public String visit(AnnotationValue av) {
+            return AnnotationValueVisitor.super.visit(av);
+        }
+
+        @Override
+        public String visit(AnnotationValue av, Object o) {
+            return "visit";
+        }
+
+        @Override
+        public String visitAnnotation(AnnotationMirror a, Object o)    { return throwUOE(); }
+        @Override
+        public String visitArray(List<? extends AnnotationValue> vals,
+                                   Object o)                           { return throwUOE(); }
+        @Override
+        public String visitBoolean(boolean b, Object o)                { return throwUOE(); }
+        @Override
+        public String visitByte(byte b, Object o)                      { return throwUOE(); }
+        @Override
+        public String visitChar(char c, Object o)                      { return throwUOE(); }
+        @Override
+        public String visitDouble(double d, Object o)                  { return throwUOE(); }
+        @Override
+        public String visitEnumConstant(VariableElement c, Object o)   { return throwUOE(); }
+        @Override
+        public String visitFloat(float f, Object o)                    { return throwUOE(); }
+        @Override
+        public String visitInt(int i, Object o)                        { return throwUOE(); }
+        @Override
+        public String visitLong(long i, Object o)                      { return throwUOE(); }
+        @Override
+        public String visitShort(short s, Object o)                    { return throwUOE(); }
+        @Override
+        public String visitString(String s, Object o)                  { return throwUOE(); }
+        @Override
+        public String visitType(TypeMirror t, Object o)                { return throwUOE(); }
+        @Override
+        public String visitUnknown(AnnotationValue av, Object o)       { return throwUOE(); }
+    }
+
+    private static String throwUOE() {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -88,6 +88,8 @@
                 Path path = fm.asPath(file);
                 int moduleIndex = path.getNameCount() - type.split("\\Q.\\E").length - 1;
                 String moduleName = path.getName(moduleIndex).toString();
+                if (moduleName.startsWith("jdk.incubator.")) //incubator modules not in module graph by default
+                    continue;
                 try {
                     ModuleElement me = elements.getModuleElement(moduleName);
                     me.getClass();
--- a/langtools/test/tools/javadoc/8147801/T8147801.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javadoc/8147801/T8147801.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -32,6 +32,8 @@
  */
 
 import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.nio.file.ClosedFileSystemException;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -80,19 +82,22 @@
     void test(boolean withOption) {
         System.err.println("Testing " + (withOption ? "with" : "without") + " option");
         try {
+            String dump = "";
             RootDoc root = getRootDoc(withOption);
             for (ClassDoc cd: root.specifiedClasses()) {
-                dump("", cd);
+                dump += dump(cd);
             }
-            if (!withOption) {
-                error("expected option did not occur");
+            if (dump.contains("lib.Lib2.i")) {
+                if (!withOption) {
+                    error("control case failed: Lib2 class file was read, unexpectedly, without using option");
+                }
+            } else {
+                if (withOption) {
+                    error("test case failed: could not read Lib2 class file, using option");
+                }
             }
         } catch (ClosedFileSystemException e) {
-            if (withOption) {
-                error("Unexpected exception: " + e);
-            } else {
-                System.err.println("Exception received as expected: " + e);
-            }
+            error("Unexpected exception: " + e);
         }
         System.err.println();
     }
@@ -118,12 +123,21 @@
         return cachedRoot;
     }
 
-    void dump(String prefix, ClassDoc cd) {
-        System.err.println(prefix + "class: " + cd);
+    String dump(ClassDoc cd) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        dump(pw, "", cd);
+        String out = sw.toString();
+        System.err.println(out);
+        return out;
+    }
+
+    void dump(PrintWriter out, String prefix, ClassDoc cd) {
+        out.println(prefix + "class: " + cd);
         for (FieldDoc fd: cd.fields()) {
-            System.err.println(fd);
+            out.println(prefix + "  " + fd);
             if (fd.type().asClassDoc() != null) {
-                dump(prefix + "  ", fd.type().asClassDoc());
+                dump(out, prefix + "    ", fd.type().asClassDoc());
             }
         }
     }
--- a/langtools/test/tools/javadoc/8147801/jarsrc/lib/Lib2.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javadoc/8147801/jarsrc/lib/Lib2.java	Fri Jan 20 19:10:00 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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,5 +24,5 @@
 package lib;
 
 public class Lib2 {
-    int i;
+    public int i;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/TestScriptInComment.java	Fri Jan 20 19:10:00 2017 +0000
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8138725
+ * @summary test --allow-script-in-comments
+ * @modules jdk.javadoc/com.sun.tools.javadoc
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Combo-style test, exercising combinations of different HTML fragments that may contain
+ * JavaScript, different places to place those fragments, and whether or not to allow the use
+ * of JavaScript.
+ */
+public class TestScriptInComment {
+    public static void main(String... args) throws Exception {
+        new TestScriptInComment().run();
+    }
+
+    /**
+     * Representative samples of different fragments of HTML that may contain JavaScript.
+     * To facilitate checking the output manually in a browser, the text "#ALERT" will be
+     * replaced by a JavaScript call of "alert(msg)", using a message string that is specific
+     * to the test case.
+     */
+    enum Comment {
+        LC("<script>#ALERT</script>", true), // script tag in Lower Case
+        UC("<SCRIPT>#ALERT</script>", true), // script tag in Upper Case
+        WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space
+        SA("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute
+        ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute
+        URI("<a href='javascript:#ALERT'>x</a>", true); // javadcript URI
+
+        /**
+         * Creates an HTML fragment to be injected into a template.
+         * @param text the HTML fragment to put into a doc comment or option.
+         * @param hasScript whether or not this fragment does contain legal JavaScript
+         * @param opts any additional options to be specified when javadoc is run
+         */
+        Comment(String text, boolean hasScript, String... opts) {
+            this.text = text;
+            this.hasScript = hasScript;
+            this.opts = Arrays.asList(opts);
+        }
+
+        final String text;
+        final boolean hasScript;
+        final List<String> opts;
+    };
+
+    /**
+     * Representative samples of positions in which javadoc may find JavaScript.
+     * Each template contains a series of strings, which are written to files or inferred as options.
+     * The first source file implies a corresponding output file which should not be written
+     * if the comment contains JavaScript and JavaScript is not allowed.
+     */
+    enum Template {
+        OVR("<html><body> overview #COMMENT </body></html>", "package p; public class C { }"),
+        PKGINFO("#COMMENT package p;", "package p; public class C { }"),
+        PKGHTML("<html><body>#COMMENT package p;</body></html>", "package p; public class C { }"),
+        CLS("package p; #COMMENT public class C { }"),
+        CON("package p; public class C { #COMMENT public C() { } }"),
+        FLD("package p; public class C { #COMMENT public int f; }"),
+        MTH("package p; public class C { #COMMENT public void m() { } }"),
+        TOP("-top", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        HDR("-header", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        FTR("-footer", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        BTM("-bottom", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        DTTL("-doctitle", "lorem #COMMENT ipsum", "package p; public class C { }"),
+        PHDR("-packagesheader", "lorem #COMMENT ipsum", "package p; public class C { }");
+
+        Template(String... args) {
+            opts = new ArrayList<String>();
+            sources = new ArrayList<String>();
+            int i = 0;
+            while (args[i].startsWith("-")) {
+                // all options being tested have a single argument that follow the option
+                opts.add(args[i++]);
+                opts.add(args[i++]);
+            }
+            while(i < args.length) {
+                sources.add(args[i++]);
+            }
+        }
+
+        // groups: 1 <html> or not;  2: package name;  3: class name
+        private final Pattern pat =
+                Pattern.compile("(?i)(<html>)?.*?(?:package ([a-z]+);.*?(?:class ([a-z]+).*)?)?");
+
+        /**
+         * Infer the file in which to write the given source.
+         * @param dir the base source directory
+         * @param src the source text
+         * @return the file in which the source should be written
+         */
+        File getSrcFile(File srcDir, String src) {
+            String f;
+            Matcher m = pat.matcher(src);
+            if (!m.matches())
+                throw new Error("match failed");
+            if (m.group(3) != null) {
+                f = m.group(2) + "/" + m.group(3) + ".java";
+            } else if (m.group(2) != null) {
+                f = m.group(2) + "/" + (m.group(1) == null ? "package-info.java" : "package.html");
+            } else {
+                f = "overview.html";
+            }
+            return new File(srcDir, f);
+        }
+
+        /**
+         * Get the options to give to javadoc.
+         * @param srcDir the srcDir to use -overview is needed
+         * @return
+         */
+        List<String> getOpts(File srcDir) {
+            if (!opts.isEmpty()) {
+                return opts;
+            } else if (sources.get(0).contains("overview")) {
+                return Arrays.asList("-overview", getSrcFile(srcDir, sources.get(0)).getPath());
+            } else {
+                return Collections.emptyList();
+            }
+        }
+
+        /**
+         * Gets the output file corresponding to the first source file.
+         * This file should not be written if the comment contains JavaScript and JavaScripot is
+         * not allowed.
+         * @param dir the base output directory
+         * @return the output file
+         */
+        File getOutFile(File outDir) {
+            String f;
+            Matcher m = pat.matcher(sources.get(0));
+            if (!m.matches())
+                throw new Error("match failed");
+            if (m.group(3) != null) {
+                f = m.group(2) + "/" + m.group(3) + ".html";
+            } else if (m.group(2) != null) {
+                f = m.group(2) + "/package-summary.html";
+            } else {
+                f = "overview-summary.html";
+            }
+            return new File(outDir, f);
+        }
+
+        final List<String> opts;
+        final List<String> sources;
+    };
+
+    enum Option {
+        OFF(null),
+        ON("--allow-script-in-comments");
+
+        Option(String text) {
+            this.text = text;
+        }
+
+        final String text;
+    };
+
+    private PrintStream out = System.err;
+
+    public void run() throws Exception {
+        int count = 0;
+        for (Template template: Template.values()) {
+            for (Comment comment: Comment.values()) {
+                for (Option option: Option.values()) {
+                    if (test(template, comment, option)) {
+                        count++;
+                    }
+                }
+            }
+        }
+
+        out.println(count + " test cases run");
+        if (errors > 0) {
+            throw new Exception(errors + " errors occurred");
+        }
+    }
+
+    boolean test(Template template, Comment comment, Option option) throws IOException {
+        if (option == Option.ON && !comment.hasScript) {
+            // skip --allowScriptInComments if comment does not contain JavaScript
+            return false;
+        }
+
+        String test = template + "-" + comment + "-" + option;
+        out.println("Test: " + test);
+
+        File dir = new File(test);
+        dir.mkdirs();
+        File srcDir = new File(dir, "src");
+        File outDir = new File(dir, "out");
+
+        String alert = "alert(\"" + test + "\");";
+        for (String src: template.sources) {
+            writeFile(template.getSrcFile(srcDir, src),
+                src.replace("#COMMENT",
+                        "/** " + comment.text.replace("#ALERT", alert) + " **/"));
+        }
+
+        List<String> opts = new ArrayList<String>();
+        opts.add("-sourcepath");
+        opts.add(srcDir.getPath());
+        opts.add("-d");
+        opts.add(outDir.getPath());
+        if (option.text != null)
+            opts.add(option.text);
+        for (String opt: template.getOpts(srcDir)) {
+            opts.add(opt.replace("#COMMENT", comment.text.replace("#ALERT", alert)));
+        }
+        opts.addAll(comment.opts);
+        opts.add("-noindex");   // index not required; save time/space writing files
+        opts.add("p");
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = javadoc(opts, pw);
+        pw.close();
+        String log = sw.toString();
+        writeFile(new File(dir, "log.txt"), log);
+
+        out.println("opts: " + opts);
+        out.println("  rc: " + rc);
+        out.println(" log:");
+        out.println(log);
+
+        String ERROR = "Use --allow-script-in-comment";
+        File outFile = template.getOutFile(outDir);
+
+        boolean expectErrors = comment.hasScript && (option == Option.OFF);
+
+        if (expectErrors) {
+            check(rc != 0, "unexpected exit code: " + rc);
+            check(log.contains(ERROR), "expected error message not found");
+            check(!outFile.exists(), "output file found unexpectedly");
+        } else {
+            check(rc == 0, "unexpected exit code: " + rc);
+            check(!log.contains(ERROR), "error message found");
+            check(outFile.exists(), "output file not found");
+        }
+
+        out.println();
+        return true;
+    }
+
+    int javadoc(List<String> opts, PrintWriter pw) {
+        return com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw,
+                "com.sun.tools.doclets.standard.Standard", opts.toArray(new String[opts.size()]));
+    }
+
+    File writeFile(File f, String text) throws IOException {
+        f.getParentFile().mkdirs();
+        FileWriter fw = new FileWriter(f);
+        try {
+            fw.write(text);
+        } finally {
+            fw.close();
+        }
+        return f;
+    }
+
+    void check(boolean cond, String errMessage) {
+        if (!cond) {
+            error(errMessage);
+        }
+    }
+
+    void error(String message) {
+        out.println("Error: " + message);
+        errors++;
+    }
+
+    int errors = 0;
+}
+
--- a/langtools/test/tools/javap/T7004698.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/javap/T7004698.java	Fri Jan 20 19:10:00 2017 +0000
@@ -42,6 +42,7 @@
         File srcFile = new File(srcDir, T7004698.class.getSimpleName() + ".java");
         File classesDir = new File(".");
         compile("-Xjcov",
+                "--add-modules", "jdk.jdeps",
                 "--add-exports", "jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED",
                 "-d", classesDir.getPath(),
                 srcFile.getPath());
--- a/langtools/test/tools/jdeps/APIDeps.java	Wed Jul 05 22:43:19 2017 +0200
+++ b/langtools/test/tools/jdeps/APIDeps.java	Fri Jan 20 19:10:00 2017 +0000
@@ -60,6 +60,9 @@
         Path testsrc = Paths.get(System.getProperty("test.src"));
         List<String> options = new ArrayList<>();
 
+        // jdk.jdeps is a service provider module so needs to be explicitly included
+        options.add("--add-modules=jdk.jdeps");
+
         // add --add-exports
         String testModules = System.getProperty("test.modules", "");
         List<String> addExports = new ArrayList<>();