Merge
authorlana
Sun, 20 Jan 2013 23:39:11 -0800
changeset 15372 e960ff5ee9a2
parent 15369 2ae199ad2e5d (diff)
parent 15167 f627eff81962 (current diff)
child 15373 2fd24f81bbe8
Merge
common/autoconf/closed.version.numbers
common/autoconf/version.numbers
jdk/make/tools/swing-beans/beaninfo/BeanInfoUtils.java
jdk/make/tools/swing-beans/beaninfo/SwingBeanInfoBase.java
jdk/src/share/demo/jfc/CodePointIM/CodePointInputMethod.java
jdk/src/share/demo/jfc/CodePointIM/CodePointInputMethodDescriptor.java
--- a/langtools/make/build.properties	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/make/build.properties	Sun Jan 20 23:39:11 2013 -0800
@@ -29,18 +29,18 @@
 # Override this path as needed, either on the command line or in
 # one of the standard user build.properties files (see build.xml)
 
-# boot.java.home = /opt/jdk/1.6.0
+# boot.java.home = /opt/jdk/1.7.0
 boot.java = ${boot.java.home}/bin/java
 boot.javac = ${boot.java.home}/bin/javac
-boot.javac.source = 6
-boot.javac.target = 6
+boot.javac.source = 7
+boot.javac.target = 7
 
 # This is the JDK used to run the product version of the tools,
 # for example, for testing. If you're building a complete JDK, specify that.
 # Override this path as needed, either on the command line or in
 # one of the standard user build.properties files (see build.xml)
 
-# target.java.home = /opt/jdk/1.7.0
+# target.java.home = /opt/jdk/1.8.0
 target.java = ${target.java.home}/bin/java
 
 # Version info -- override as needed
@@ -161,6 +161,14 @@
 
 #
 
+sjavac.includes = \
+        com/sun/tools/sjavac/ 
+
+sjavac.tests = \
+        tools/sjavac
+        
+#
+
 # The following files require the latest JDK to be available.
 # The API can be provided by using a suitable boot.java.home
 # or by setting import.jdk
--- a/langtools/make/build.xml	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/make/build.xml	Sun Jan 20 23:39:11 2013 -0800
@@ -241,15 +241,15 @@
     </target>
 
     <target name="build-bootstrap-tools"
-        depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah"
+        depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah,build-bootstrap-sjavac"
     />
 
     <target name="build-all-tools"
-        depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap"
+        depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap,build-sjavac"
     />
 
     <target name="build-all-classes" depends="build-bootstrap-javac,-create-import-jdk-stubs">
-        <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes}"/>
+        <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes} ${sjavac.includes}"/>
     </target>
 
     <!-- clean -->
@@ -656,6 +656,40 @@
 
     <target name="javap" depends="build-javap,jtreg-javap,findbugs-javap"/>
 
+    <!--
+    **** sjavac targets.
+    -->
+
+    <target name="build-bootstrap-sjavac"
+            depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+        <build-bootstrap-classes includes="${sjavac.includes}"/>
+        <build-bootstrap-jar     name="sjavac" includes="${sjavac.includes}"
+                                 jarmainclass="com.sun.tools.sjavac.Main"/>
+        <build-bootstrap-tool    name="sjavac"/>
+    </target>
+
+    <target name="build-classes-sjavac" depends="build-classes-javac">
+        <build-classes includes="${sjavac.includes}"/>
+    </target>
+
+    <target name="build-sjavac" depends="build-classes-sjavac">
+        <build-jar  name="sjavac" includes="${sjavac.includes}"
+                    jarmainclass="com.sun.tools.sjavac.Main"
+                    jarclasspath="sjavac.jar"/>
+        <build-tool name="sjavac"/>
+    </target>
+    
+    <!-- (no javadoc for javap) -->
+
+    <target name="jtreg-sjavac" depends="build-sjavac,-def-jtreg">
+        <jtreg-tool name="sjavac" tests="${sjavac.tests}"/>
+    </target>
+
+    <target name="findbugs-sjavac" depends="build-sjavac,-def-findbugs">
+        <findbugs-tool name="sjavac"/>
+    </target>
+
+    <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
 
     <!--
     **** Create import JDK stubs.
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,10 @@
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.doclint.DocLint;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javadoc.RootDocImpl;
 
 /**
  * Configure the output based on the command line options.
@@ -172,6 +174,11 @@
     public boolean createoverview = false;
 
     /**
+     * Collected set of doclint options
+     */
+    public Set<String> doclintOpts = new LinkedHashSet<String>();
+
+    /**
      * Unique Resource Handler for this package.
      */
     public final MessageRetriever standardmessage;
@@ -255,6 +262,10 @@
                 nooverview = true;
             } else if (opt.equals("-overview")) {
                 overview = true;
+            } else if (opt.equals("-xdoclint")) {
+                doclintOpts.add(null);
+            } else if (opt.startsWith("-xdoclint:")) {
+                doclintOpts.add(opt.substring(opt.indexOf(":") + 1));
             }
         }
         if (root.specifiedClasses().length > 0) {
@@ -270,6 +281,10 @@
         }
         setCreateOverview();
         setTopFile(root);
+
+        if (root instanceof RootDocImpl) {
+            ((RootDocImpl) root).initDocLint(doclintOpts);
+        }
     }
 
     /**
@@ -303,7 +318,9 @@
             option.equals("-serialwarn") ||
             option.equals("-use") ||
             option.equals("-nonavbar") ||
-            option.equals("-nooverview")) {
+            option.equals("-nooverview") ||
+            option.equals("-xdoclint") ||
+            option.startsWith("-xdoclint:")) {
             return 1;
         } else if (option.equals("-help")) {
             System.out.println(getText("doclet.usage"));
@@ -410,6 +427,16 @@
                     return false;
                 }
                 noindex = true;
+            } else if (opt.startsWith("-xdoclint:")) {
+                if (opt.contains("/")) {
+                    reporter.printError(getText("doclet.Option_doclint_no_qualifiers"));
+                    return false;
+                }
+                if (!DocLint.isValidOption(
+                        opt.replace("-xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX))) {
+                    reporter.printError(getText("doclet.Option_doclint_invalid_arg"));
+                    return false;
+                }
             }
         }
         return true;
@@ -506,8 +533,8 @@
      */
     @Override
     public Locale getLocale() {
-        if (root instanceof com.sun.tools.javadoc.RootDocImpl)
-            return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale();
+        if (root instanceof RootDocImpl)
+            return ((RootDocImpl)root).getLocale();
         else
             return Locale.getDefault();
     }
@@ -518,8 +545,8 @@
     @Override
     public JavaFileManager getFileManager() {
         if (fileManager == null) {
-            if (root instanceof com.sun.tools.javadoc.RootDocImpl)
-                fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager();
+            if (root instanceof RootDocImpl)
+                fileManager = ((RootDocImpl) root).getFileManager();
             else
                 fileManager = new JavacFileManager(new Context(), false, null);
         }
@@ -527,4 +554,12 @@
     }
 
     private JavaFileManager fileManager;
+
+    @Override
+    public boolean showMessage(SourcePosition pos, String key) {
+        if (root instanceof RootDocImpl) {
+            return pos == null || ((RootDocImpl) root).showTagMessages();
+        }
+        return true;
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -781,4 +781,6 @@
         sourcetab = n;
         tabSpaces = String.format("%" + n + "s", "");
     }
+
+    public abstract boolean showMessage(SourcePosition pos, String key);
 }
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Sun Jan 20 23:39:11 2013 -0800
@@ -11,6 +11,8 @@
 doclet.Class_0_extends_implements_serializable=Class {0} extends {1} implements Serializable
 doclet.Option_conflict=Option {0} conflicts with {1}
 doclet.Option_reuse=Option reused: {0}
+doclet.Option_doclint_no_qualifiers=Access qualifiers not permitted for -Xdoclint arguments
+doclet.Option_doclint_invalid_arg=Invalid argument for -Xdoclint option
 doclet.exception_encountered= {0} encountered \n\
 \twhile attempting to create file: {1}
 doclet.perform_copy_exception_encountered= {0} encountered while \n\
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,9 +60,9 @@
     private ResourceBundle messageRB;
 
     /**
-     * Initilize the ResourceBundle with the given resource.
+     * Initialize the ResourceBundle with the given resource.
      *
-     * @param rb the esource bundle to read.
+     * @param rb the resource bundle to read.
      */
     public MessageRetriever(ResourceBundle rb) {
         this.configuration = null;
@@ -71,7 +71,7 @@
     }
 
     /**
-     * Initilize the ResourceBundle with the given resource.
+     * Initialize the ResourceBundle with the given resource.
      *
      * @param configuration the configuration
      * @param resourcelocation Resource.
@@ -189,7 +189,8 @@
      * @param args arguments to be replaced in the message.
      */
     public void warning(SourcePosition pos, String key, Object... args) {
-        printWarning(pos, getText(key, args));
+        if (configuration.showMessage(pos, key))
+            printWarning(pos, getText(key, args));
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 package com.sun.tools.doclint;
 
+import com.sun.source.doctree.LiteralTree;
 import java.util.regex.Matcher;
 import com.sun.source.doctree.LinkTree;
 import java.net.URI;
@@ -359,9 +360,8 @@
             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
         } else if (t.endKind == HtmlTag.EndKind.NONE) {
             env.messages.error(HTML, tree, "dc.tag.end.not.permitted", treeName);
-        } else if (tagStack.isEmpty()) {
-            env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
         } else {
+            boolean done = false;
             while (!tagStack.isEmpty()) {
                 TagStackItem top = tagStack.peek();
                 if (t == top.tag) {
@@ -383,6 +383,7 @@
                         env.messages.error(HTML, tree, "dc.text.not.allowed", treeName);
                     }
                     tagStack.pop();
+                    done = true;
                     break;
                 } else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
                     tagStack.pop();
@@ -400,10 +401,15 @@
                         tagStack.pop();
                     } else {
                         env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+                        done = true;
                         break;
                     }
                 }
             }
+
+            if (!done && tagStack.isEmpty()) {
+                env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+            }
         }
 
         return super.visitEndElement(tree, ignore);
@@ -447,14 +453,18 @@
                         if (currTag != HtmlTag.A) {
                             break;
                         }
-                    // fallthrough
+                        // fallthrough
                     case ID:
                         String value = getAttrValue(tree);
-                        if (!validName.matcher(value).matches()) {
-                            env.messages.error(HTML, tree, "dc.invalid.anchor", value);
-                        }
-                        if (!foundAnchors.add(value)) {
-                            env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+                        if (value == null) {
+                            env.messages.error(HTML, tree, "dc.anchor.value.missing");
+                        } else {
+                            if (!validName.matcher(value).matches()) {
+                                env.messages.error(HTML, tree, "dc.invalid.anchor", value);
+                            }
+                            if (!foundAnchors.add(value)) {
+                                env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+                            }
                         }
                         break;
 
@@ -542,6 +552,19 @@
     }
 
     @Override
+    public Void visitLiteral(LiteralTree tree, Void ignore) {
+        if (tree.getKind() == DocTree.Kind.CODE) {
+            for (TagStackItem tsi: tagStack) {
+                if (tsi.tag == HtmlTag.CODE) {
+                    env.messages.warning(HTML, tree, "dc.tag.code.within.code");
+                    break;
+                }
+            }
+        }
+        return super.visitLiteral(tree, ignore);
+    }
+
+    @Override
     public Void visitParam(ParamTree tree, Void ignore) {
         boolean typaram = tree.isTypeParameter();
         IdentifierTree nameTree = tree.getName();
--- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 #
 
 dc.anchor.already.defined = anchor already defined: {0}
+dc.anchor.value.missing = no value given for anchor
 dc.attr.lacks.value = attribute lacks value
 dc.attr.obsolete = attribute obsolete: {0}
 dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0}
@@ -47,6 +48,7 @@
 dc.no.summary.or.caption.for.table=no summary or caption for table
 dc.param.name.not.found = @param name not found
 dc.ref.not.found = reference not found
+dc.tag.code.within.code = '{@code'} within <code>
 dc.tag.empty = empty <{0}> tag
 dc.tag.end.not.permitted = invalid end tag: </{0}>
 dc.tag.end.unexpected = unexpected end tag: </{0}>
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,12 +126,12 @@
             //
             // We need to do this in two passes because when creating
             // a container for a repeating annotation we must
-            // guarantee that the @ContainedBy on the
+            // guarantee that the @Repeatable on the
             // contained annotation is fully annotated
             //
             // The way we force this order is to do all repeating
             // annotations in a pass after all non-repeating are
-            // finished. This will work because @ContainedBy
+            // finished. This will work because @Repeatable
             // is non-repeating and therefore will be annotated in the
             // fist pass.
 
@@ -261,7 +261,7 @@
             // its contained annotation.
             ListBuffer<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
             if (manualContainer != null) {
-                log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present",
+                log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
                         manualContainer.first().type.tsym);
             }
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -450,7 +450,7 @@
      * This is the implementation for {@code
      * javax.lang.model.element.Element.getAnnotationMirrors()}.
      */
-    public final List<Attribute.Compound> getAnnotationMirrors() {
+    public final List<? extends AnnotationMirror> getAnnotationMirrors() {
         return getRawAttributes();
     }
 
@@ -462,6 +462,11 @@
         return JavacElements.getAnnotation(this, annoType);
     }
 
+    // This method is part of the javax.lang.model API, do not use this in javac code.
+    public <A extends java.lang.annotation.Annotation> A[] getAnnotations(Class<A> annoType) {
+        return JavacElements.getAnnotations(this, annoType);
+    }
+
     // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
     public java.util.List<Symbol> getEnclosedElements() {
         return List.nil();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -161,10 +161,10 @@
     public final Type autoCloseableType;
     public final Type trustMeType;
     public final Type lambdaMetafactory;
-    public final Type containedByType;
-    public final Type containerForType;
+    public final Type repeatableType;
     public final Type documentedType;
     public final Type elementTypeType;
+    public final Type functionalInterfaceType;
 
     /** The symbol representing the length field of an array.
      */
@@ -494,8 +494,7 @@
         deprecatedType = enterClass("java.lang.Deprecated");
         suppressWarningsType = enterClass("java.lang.SuppressWarnings");
         inheritedType = enterClass("java.lang.annotation.Inherited");
-        containedByType = enterClass("java.lang.annotation.ContainedBy");
-        containerForType = enterClass("java.lang.annotation.ContainerFor");
+        repeatableType = enterClass("java.lang.annotation.Repeatable");
         documentedType = enterClass("java.lang.annotation.Documented");
         elementTypeType = enterClass("java.lang.annotation.ElementType");
         systemType = enterClass("java.lang.System");
@@ -509,6 +508,7 @@
         nativeHeaderType = enterClass("java.lang.annotation.Native");
         nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
         lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
+        functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
 
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Sun Jan 20 23:39:11 2013 -0800
@@ -392,9 +392,9 @@
          * Compute the function descriptor associated with a given functional interface
          */
         public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
-            if (!origin.isInterface()) {
+            if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
                 //t must be an interface
-                throw failure("not.a.functional.intf");
+                throw failure("not.a.functional.intf", origin);
             }
 
             final ListBuffer<Symbol> abstracts = ListBuffer.lb();
@@ -406,13 +406,13 @@
                     abstracts.append(sym);
                 } else {
                     //the target method(s) should be the only abstract members of t
-                    throw failure("not.a.functional.intf.1",
+                    throw failure("not.a.functional.intf.1",  origin,
                             diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin));
                 }
             }
             if (abstracts.isEmpty()) {
                 //t must define a suitable non-generic method
-                throw failure("not.a.functional.intf.1",
+                throw failure("not.a.functional.intf.1", origin,
                             diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
             } else if (abstracts.size() == 1) {
                 return new FunctionDescriptor(abstracts.first());
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -392,7 +392,7 @@
                     List.of(p)));
 
             if (!chk.annotationApplicable(annoTree, on))
-                log.error(annoTree.pos(), "invalid.containedby.annotation.incompatible.target", targetContainerType, origAnnoType);
+                log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
 
             if (!chk.validateAnnotationDeferErrors(annoTree))
                 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
@@ -414,11 +414,11 @@
         Type origAnnoType = currentAnno.type;
         TypeSymbol origAnnoDecl = origAnnoType.tsym;
 
-        // Fetch the ContainedBy annotation from the current
+        // Fetch the Repeatable annotation from the current
         // annotation's declaration, or null if it has none
-        Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym);
-        if (ca == null) { // has no ContainedBy annotation
-            log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.containedByType);
+        Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
+        if (ca == null) { // has no Repeatable annotation
+            log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
             return null;
         }
 
@@ -440,23 +440,23 @@
             DiagnosticPosition pos,
             TypeSymbol annoDecl)
     {
-        // The next three checks check that the ContainedBy annotation
+        // The next three checks check that the Repeatable annotation
         // on the declaration of the annotation type that is repeating is
         // valid.
 
-        // ContainedBy must have at least one element
+        // Repeatable must have at least one element
         if (ca.values.isEmpty()) {
-            log.error(pos, "invalid.containedby.annotation", annoDecl);
+            log.error(pos, "invalid.repeatable.annotation", annoDecl);
             return null;
         }
         Pair<MethodSymbol,Attribute> p = ca.values.head;
         Name name = p.fst.name;
         if (name != names.value) { // should contain only one element, named "value"
-            log.error(pos, "invalid.containedby.annotation", annoDecl);
+            log.error(pos, "invalid.repeatable.annotation", annoDecl);
             return null;
         }
         if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
-            log.error(pos, "invalid.containedby.annotation", annoDecl);
+            log.error(pos, "invalid.repeatable.annotation", annoDecl);
             return null;
         }
 
@@ -491,13 +491,13 @@
         }
         if (error) {
             log.error(pos,
-                      "invalid.containedby.annotation.multiple.values",
+                      "invalid.repeatable.annotation.multiple.values",
                       targetContainerType,
                       nr_value_elems);
             return null;
         } else if (nr_value_elems == 0) {
             log.error(pos,
-                      "invalid.containedby.annotation.no.value",
+                      "invalid.repeatable.annotation.no.value",
                       targetContainerType);
             return null;
         }
@@ -506,7 +506,7 @@
         // probably "impossible" to fail this
         if (containerValueSymbol.kind != Kinds.MTH) {
             log.error(pos,
-                      "invalid.containedby.annotation.invalid.value",
+                      "invalid.repeatable.annotation.invalid.value",
                       targetContainerType);
             fatalError = true;
         }
@@ -518,7 +518,7 @@
         if (!(types.isArray(valueRetType) &&
               types.isSameType(expectedType, valueRetType))) {
             log.error(pos,
-                      "invalid.containedby.annotation.value.return",
+                      "invalid.repeatable.annotation.value.return",
                       targetContainerType,
                       valueRetType,
                       expectedType);
@@ -528,10 +528,7 @@
             fatalError = true;
         }
 
-        // Explicitly no check for/validity of @ContainerFor. That is
-        // done on declaration of the container, and at reflect time.
-
-        // The rest of the conditions for a valid containing annotation are made
+        // The conditions for a valid containing annotation are made
         // in Check.validateRepeatedAnnotaton();
 
         return fatalError ? null : containerValueSymbol;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -3844,24 +3844,14 @@
                 log.error(tree.typarams.head.pos(),
                           "intf.annotation.cant.have.type.params");
 
-            // If this annotation has a @ContainedBy, validate
-            Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym);
-            if (containedBy != null) {
-                // get diagnositc position for error reporting
-                DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type);
+            // If this annotation has a @Repeatable, validate
+            Attribute.Compound repeatable = c.attribute(syms.repeatableType.tsym);
+            if (repeatable != null) {
+                // get diagnostic position for error reporting
+                DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
                 Assert.checkNonNull(cbPos);
 
-                chk.validateContainedBy(c, containedBy, cbPos);
-            }
-
-            // If this annotation has a @ContainerFor, validate
-            Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym);
-            if (containerFor != null) {
-                // get diagnositc position for error reporting
-                DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type);
-                Assert.checkNonNull(cfPos);
-
-                chk.validateContainerFor(c, containerFor, cfPos);
+                chk.validateRepeatable(c, repeatable, cbPos);
             }
         } else {
             // Check that all extended classes and interfaces
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -634,25 +634,40 @@
         }
     }
 
+    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
+        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
+            return typeTagError(pos,
+                                diags.fragment("type.req.class.array"),
+                                asTypeParam(t));
+        } else {
+            return t;
+        }
+    }
+
     /** Check that type is a class or interface type.
      *  @param pos           Position to be used for error reporting.
      *  @param t             The type to be checked.
      */
     Type checkClassType(DiagnosticPosition pos, Type t) {
-        if (!t.hasTag(CLASS) && !t.hasTag(ERROR))
+        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
             return typeTagError(pos,
                                 diags.fragment("type.req.class"),
-                                (t.hasTag(TYPEVAR))
-                                ? diags.fragment("type.parameter", t)
-                                : t);
-        else
+                                asTypeParam(t));
+        } else {
             return t;
+        }
     }
+    //where
+        private Object asTypeParam(Type t) {
+            return (t.hasTag(TYPEVAR))
+                                    ? diags.fragment("type.parameter", t)
+                                    : t;
+        }
 
     /** Check that type is a valid qualifier for a constructor reference expression
      */
     Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
-        t = checkClassType(pos, t);
+        t = checkClassOrArrayType(pos, t);
         if (t.hasTag(CLASS)) {
             if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
                 log.error(pos, "abstract.cant.be.instantiated");
@@ -690,11 +705,8 @@
      *  @param t             The type to be checked.
      */
     Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
-        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
-            return typeTagError(pos,
-                                diags.fragment("type.req.class.array"),
-                                t);
-        } else if (!types.isReifiable(t)) {
+        t = checkClassOrArrayType(pos, t);
+        if (!t.isErroneous() && !types.isReifiable(t)) {
             log.error(pos, "illegal.generic.type.for.instof");
             return types.createErrorType(t);
         } else {
@@ -2589,33 +2601,45 @@
             if (!isOverrider(s))
                 log.error(a.pos(), "method.does.not.override.superclass");
         }
+
+        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
+            if (s.kind != TYP) {
+                log.error(a.pos(), "bad.functional.intf.anno");
+            } else {
+                try {
+                    types.findDescriptorSymbol((TypeSymbol)s);
+                } catch (Types.FunctionDescriptorLookupError ex) {
+                    log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
+                }
+            }
+        }
     }
 
     /**
-     * Validate the proposed container 'containedBy' on the
+     * Validate the proposed container 'repeatable' on the
      * annotation type symbol 's'. Report errors at position
      * 'pos'.
      *
-     * @param s The (annotation)type declaration annotated with a @ContainedBy
-     * @param containedBy the @ContainedBy on 's'
+     * @param s The (annotation)type declaration annotated with a @Repeatable
+     * @param repeatable the @Repeatable on 's'
      * @param pos where to report errors
      */
-    public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
-        Assert.check(types.isSameType(containedBy.type, syms.containedByType));
+    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
+        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
 
         Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
         if (!l.isEmpty()) {
             Assert.check(l.head.fst.name == names.value);
             t = ((Attribute.Class)l.head.snd).getValue();
         }
 
         if (t == null) {
-            log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
+            // errors should already have been reported during Annotate
             return;
         }
 
-        validateHasContainerFor(t.tsym, s, pos);
+        validateValue(t.tsym, s, pos);
         validateRetention(t.tsym, s, pos);
         validateDocumented(t.tsym, s, pos);
         validateInherited(t.tsym, s, pos);
@@ -2623,79 +2647,18 @@
         validateDefault(t.tsym, s, pos);
     }
 
-    /**
-     * Validate the proposed container 'containerFor' on the
-     * annotation type symbol 's'. Report errors at position
-     * 'pos'.
-     *
-     * @param s The (annotation)type declaration annotated with a @ContainerFor
-     * @param containerFor the @ContainedFor on 's'
-     * @param pos where to report errors
-     */
-    public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
-        Assert.check(types.isSameType(containerFor.type, syms.containerForType));
-
-        Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
-        if (!l.isEmpty()) {
-            Assert.check(l.head.fst.name == names.value);
-            t = ((Attribute.Class)l.head.snd).getValue();
-        }
-
-        if (t == null) {
-            log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
-            return;
-        }
-
-        validateHasContainedBy(t.tsym, s, pos);
-    }
-
-    private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
-        Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
-
-        if (containedBy == null) {
-            log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
-            return;
+    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+        Scope.Entry e = container.members().lookup(names.value);
+        if (e.scope != null && e.sym.kind == MTH) {
+            MethodSymbol m = (MethodSymbol) e.sym;
+            Type ret = m.getReturnType();
+            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
+                log.error(pos, "invalid.repeatable.annotation.value.return",
+                        container, ret, types.makeArrayType(contained.type));
+            }
+        } else {
+            log.error(pos, "invalid.repeatable.annotation.no.value", container);
         }
-
-        Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
-        if (!l.isEmpty()) {
-            Assert.check(l.head.fst.name == names.value);
-            t = ((Attribute.Class)l.head.snd).getValue();
-        }
-
-        if (t == null) {
-            log.error(pos, "invalid.container.wrong.containedby", container, contained);
-            return;
-        }
-
-        if (!types.isSameType(t, contained.type))
-            log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
-    }
-
-    private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
-        Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
-
-        if (containerFor == null) {
-            log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
-            return;
-        }
-
-        Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
-        if (!l.isEmpty()) {
-            Assert.check(l.head.fst.name == names.value);
-            t = ((Attribute.Class)l.head.snd).getValue();
-        }
-
-        if (t == null) {
-            log.error(pos, "invalid.container.wrong.containerfor", container, contained);
-            return;
-        }
-
-        if (!types.isSameType(t, contained.type))
-            log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
     }
 
     private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
@@ -2715,7 +2678,7 @@
             }
         }
         if (error ) {
-            log.error(pos, "invalid.containedby.annotation.retention",
+            log.error(pos, "invalid.repeatable.annotation.retention",
                       container, containerRetention,
                       contained, containedRetention);
         }
@@ -2724,7 +2687,7 @@
     private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
         if (contained.attribute(syms.documentedType.tsym) != null) {
             if (container.attribute(syms.documentedType.tsym) == null) {
-                log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
+                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
             }
         }
     }
@@ -2732,7 +2695,7 @@
     private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
         if (contained.attribute(syms.inheritedType.tsym) != null) {
             if (container.attribute(syms.inheritedType.tsym) == null) {
-                log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
+                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
             }
         }
     }
@@ -2752,7 +2715,7 @@
         // contained has target, but container has not, error
         Attribute.Array containerTarget = getAttributeTargetAttribute(container);
         if (containerTarget == null) {
-            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
             return;
         }
 
@@ -2775,7 +2738,7 @@
         }
 
         if (!isTargetSubset(containedTargets, containerTargets)) {
-            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
         }
     }
 
@@ -2809,7 +2772,7 @@
                 elm.kind == Kinds.MTH &&
                 ((MethodSymbol)elm).defaultValue == null) {
                 log.error(pos,
-                          "invalid.containedby.annotation.elem.nondefault",
+                          "invalid.repeatable.annotation.elem.nondefault",
                           container,
                           elm);
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,7 +131,11 @@
 
         predefClassDef = make.ClassDef(
             make.Modifiers(PUBLIC),
-            syms.predefClass.name, null, null, null, null);
+            syms.predefClass.name,
+            List.<JCTypeParameter>nil(),
+            null,
+            List.<JCExpression>nil(),
+            List.<JCTree>nil());
         predefClassDef.sym = syms.predefClass;
         todo = Todo.instance(context);
         fileManager = context.get(JavaFileManager.class);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Sun Jan 20 23:39:11 2013 -0800
@@ -302,6 +302,7 @@
             case UNBOUND:           /** Type :: instMethod */
             case STATIC:            /** Type :: staticMethod */
             case TOPLEVEL:          /** Top level :: new */
+            case ARRAY_CTOR:        /** ArrayType :: new */
                 init = null;
                 break;
 
@@ -645,24 +646,33 @@
          * to the first bridge synthetic parameter
          */
         private JCExpression bridgeExpressionNew() {
-            JCExpression encl = null;
-            switch (tree.kind) {
-                case UNBOUND:
-                case IMPLICIT_INNER:
-                    encl = make.Ident(params.first());
-            }
+            if (tree.kind == ReferenceKind.ARRAY_CTOR) {
+                //create the array creation expression
+                JCNewArray newArr = make.NewArray(make.Type(types.elemtype(tree.getQualifierExpression().type)),
+                        List.of(make.Ident(params.first())),
+                        null);
+                newArr.type = tree.getQualifierExpression().type;
+                return newArr;
+            } else {
+                JCExpression encl = null;
+                switch (tree.kind) {
+                    case UNBOUND:
+                    case IMPLICIT_INNER:
+                        encl = make.Ident(params.first());
+                }
 
-            //create the instance creation expression
-            JCNewClass newClass = make.NewClass(encl,
-                    List.<JCExpression>nil(),
-                    make.Type(tree.getQualifierExpression().type),
-                    convertArgs(tree.sym, args.toList(), tree.varargsElement),
-                    null);
-            newClass.constructor = tree.sym;
-            newClass.constructorType = tree.sym.erasure(types);
-            newClass.type = tree.getQualifierExpression().type;
-            setVarargsIfNeeded(newClass, tree.varargsElement);
-            return newClass;
+                //create the instance creation expression
+                JCNewClass newClass = make.NewClass(encl,
+                        List.<JCExpression>nil(),
+                        make.Type(tree.getQualifierExpression().type),
+                        convertArgs(tree.sym, args.toList(), tree.varargsElement),
+                        null);
+                newClass.constructor = tree.sym;
+                newClass.constructorType = tree.sym.erasure(types);
+                newClass.type = tree.getQualifierExpression().type;
+                setVarargsIfNeeded(newClass, tree.varargsElement);
+                return newClass;
+            }
         }
 
         private VarSymbol addParameter(String name, Type p, boolean genArg) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sun Jan 20 23:39:11 2013 -0800
@@ -2386,10 +2386,23 @@
                                   List<Type> typeargtypes,
                                   boolean boxingAllowed) {
         MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
+
+        ReferenceLookupHelper boundLookupHelper;
+        if (!name.equals(names.init)) {
+            //method reference
+            boundLookupHelper =
+                    new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+        } else if (site.hasTag(ARRAY)) {
+            //array constructor reference
+            boundLookupHelper =
+                    new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
+        } else {
+            //class constructor reference
+            boundLookupHelper =
+                    new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
+        }
+
         //step 1 - bound lookup
-        ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
-                new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) :
-                new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper);
 
@@ -2627,6 +2640,33 @@
     }
 
     /**
+     * Helper class for array constructor lookup; an array constructor lookup
+     * is simulated by looking up a method that returns the array type specified
+     * as qualifier, and that accepts a single int parameter (size of the array).
+     */
+    class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
+
+        ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
+                List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+            super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
+        }
+
+        @Override
+        protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+            Scope sc = new Scope(syms.arrayClass);
+            MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
+            arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass);
+            sc.enter(arrayConstr);
+            return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
+        }
+
+        @Override
+        ReferenceKind referenceKind(Symbol sym) {
+            return ReferenceKind.ARRAY_CTOR;
+        }
+    }
+
+    /**
      * Helper class for constructor reference lookup. The lookup logic is based
      * upon either Resolve.findMethod or Resolve.findDiamond - depending on
      * whether the constructor reference needs diamond inference (this is the case
@@ -3381,7 +3421,10 @@
 
         @Override
         protected Symbol access(Name name, TypeSymbol location) {
-            return ambiguousSyms.last();
+            Symbol firstAmbiguity = ambiguousSyms.last();
+            return firstAmbiguity.kind == TYP ?
+                    types.createErrorType(name, location, firstAmbiguity.type).tsym :
+                    firstAmbiguity;
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,8 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Inherited;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.Map;
 
 import javax.lang.model.SourceVersion;
@@ -96,32 +98,43 @@
         enter = Enter.instance(context);
     }
 
-
     /**
-     * An internal-use utility that creates a reified annotation.
+     * An internal-use utility that creates a runtime view of an
+     * annotation. This is the implementation of
+     * Element.getAnnotation(Class).
      */
     public static <A extends Annotation> A getAnnotation(Symbol annotated,
                                                          Class<A> annoType) {
         if (!annoType.isAnnotation())
             throw new IllegalArgumentException("Not an annotation type: "
                                                + annoType);
-        String name = annoType.getName();
-        for (Attribute.Compound anno : annotated.getAnnotationMirrors())
-            if (name.equals(anno.type.tsym.flatName().toString()))
-                return AnnotationProxyMaker.generateAnnotation(anno, annoType);
-        return null;
+        Attribute.Compound c;
+        if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
+            c = getAttributeOnClass((ClassSymbol)annotated, annoType);
+        } else {
+            c = getAttribute(annotated, annoType);
+        }
+        return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
     }
 
-    /**
-     * An internal-use utility that creates a reified annotation.
-     * This overloaded version take annotation inheritance into account.
-     */
-    public static <A extends Annotation> A getAnnotation(ClassSymbol annotated,
-                                                         Class<A> annoType) {
+    // Helper to getAnnotation[s]
+    private static <A extends Annotation> Attribute.Compound getAttribute(Symbol annotated,
+                                                                          Class<A> annoType) {
+        String name = annoType.getName();
+
+        for (Attribute.Compound anno : annotated.getRawAttributes())
+            if (name.equals(anno.type.tsym.flatName().toString()))
+                return anno;
+
+        return null;
+    }
+    // Helper to getAnnotation[s]
+    private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
+                                                                Class<A> annoType) {
         boolean inherited = annoType.isAnnotationPresent(Inherited.class);
-        A result = null;
+        Attribute.Compound result = null;
         while (annotated.name != annotated.name.table.names.java_lang_Object) {
-            result = getAnnotation((Symbol)annotated, annoType);
+            result = getAttribute(annotated, annoType);
             if (result != null || !inherited)
                 break;
             Type sup = annotated.getSuperclass();
@@ -132,6 +145,189 @@
         return result;
     }
 
+    /**
+     * An internal-use utility that creates a runtime view of
+     * annotations. This is the implementation of
+     * Element.getAnnotations(Class).
+     */
+    public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
+                                                            Class<A> annoType) {
+        if (!annoType.isAnnotation())
+            throw new IllegalArgumentException("Not an annotation type: "
+                                               + annoType);
+        // If annoType does not declare a container this is equivalent to wrapping
+        // getAnnotation(...) in an array.
+        Class <? extends Annotation> containerType = getContainer(annoType);
+        if (containerType == null) {
+            A res = getAnnotation(annotated, annoType);
+            int size;
+            if (res == null) {
+                size = 0;
+            } else {
+                size = 1;
+            }
+            @SuppressWarnings("unchecked") // annoType is the Class for A
+            A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
+            if (res != null)
+                arr[0] = res;
+            return arr;
+        }
+
+        // So we have a containing type
+        String name = annoType.getName();
+        String annoTypeName = annoType.getSimpleName();
+        String containerTypeName = containerType.getSimpleName();
+        int directIndex = -1, containerIndex = -1;
+        Attribute.Compound direct = null, container = null;
+        Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
+
+        // Find directly present annotations
+        for (int i = 0; i < rawAttributes.length; i++) {
+            if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
+                directIndex = i;
+                direct = rawAttributes[i];
+            } else if(containerTypeName != null &&
+                      containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
+                containerIndex = i;
+                container = rawAttributes[i];
+            }
+        }
+        // Deal with inherited annotations
+        if (annotated.kind == Kinds.TYP &&
+                (annotated instanceof ClassSymbol)) {
+            ClassSymbol s = (ClassSymbol)annotated;
+            if (direct == null && container == null) {
+                direct = getAttributeOnClass(s, annoType);
+                container = getAttributeOnClass(s, containerType);
+
+                // both are inherited and found, put container last
+                if (direct != null && container != null) {
+                    directIndex = 0;
+                    containerIndex = 1;
+                } else if (direct != null) {
+                    directIndex = 0;
+                } else {
+                    containerIndex = 0;
+                }
+            } else if (direct == null) {
+                direct = getAttributeOnClass(s, annoType);
+                if (direct != null)
+                    directIndex = containerIndex + 1;
+            } else if (container == null) {
+                container = getAttributeOnClass(s, containerType);
+                if (container != null)
+                    containerIndex = directIndex + 1;
+            }
+        }
+
+        // Pack them in an array
+        Attribute[] contained0 = new Attribute[0];
+        if (container != null)
+            contained0 = unpackAttributes(container);
+        ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
+        for (Attribute a : contained0)
+            if (a instanceof Attribute.Compound)
+                compounds = compounds.append((Attribute.Compound)a);
+        Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
+
+        int size = (direct == null ? 0 : 1) + contained.length;
+        @SuppressWarnings("unchecked") // annoType is the Class for A
+        A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
+
+        // if direct && container, which is first?
+        int insert = -1;
+        int length = arr.length;
+        if (directIndex >= 0 && containerIndex >= 0) {
+            if (directIndex < containerIndex) {
+                arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+                insert = 1;
+            } else {
+                arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+                insert = 0;
+                length--;
+            }
+        } else if (directIndex >= 0) {
+            arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+            return arr;
+        } else {
+            // Only container
+            insert = 0;
+        }
+
+        for (int i = 0; i + insert < length; i++)
+            arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
+
+        return arr;
+    }
+
+    // Needed to unpack the runtime view of containing annotations
+    private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
+    private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
+
+    private static Class<? extends Annotation> initRepeatable() {
+        try {
+            // Repeatable will not be available when bootstrapping on
+            // JDK 7 so use a reflective lookup instead of a class
+            // literal for Repeatable.class.
+            return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
+        } catch (ClassNotFoundException e) {
+            return null;
+        } catch (SecurityException e) {
+            return null;
+        }
+    }
+    private static Method initValueElementMethod() {
+        if (REPEATABLE_CLASS == null)
+            return null;
+
+        Method m = null;
+        try {
+            m = REPEATABLE_CLASS.getMethod("value");
+            if (m != null)
+                m.setAccessible(true);
+            return m;
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    // Helper to getAnnotations
+    private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
+        // Since we can not refer to java.lang.annotation.Repeatable until we are
+        // bootstrapping with java 8 we need to get the Repeatable annotation using
+        // reflective invocations instead of just using its type and element method.
+        if (REPEATABLE_CLASS != null &&
+            VALUE_ELEMENT_METHOD != null) {
+            // Get the Repeatable instance on the annotations declaration
+            Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
+            if (repeatable != null) {
+                try {
+                    // Get the value element, it should be a class
+                    // indicating the containing annotation type
+                    @SuppressWarnings("unchecked")
+                    Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
+                    if (containerType == null)
+                        return null;
+
+                    return containerType;
+                } catch (ClassCastException e) {
+                    return null;
+                } catch (IllegalAccessException e) {
+                    return null;
+                } catch (InvocationTargetException e ) {
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+    // Helper to getAnnotations
+    private static Attribute[] unpackAttributes(Attribute.Compound container) {
+        // We now have an instance of the container,
+        // unpack it returning an instance of the
+        // contained type or null
+        return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
+    }
 
     public PackageSymbol getPackageElement(CharSequence name) {
         String strName = name.toString();
@@ -238,8 +434,10 @@
         tree.accept(vis);
         if (vis.result == null)
             return null;
+
+        List<Attribute.Compound> annos = sym.getRawAttributes();
         return matchAnnoToTree(cast(Attribute.Compound.class, findme),
-                               sym.getAnnotationMirrors(),
+                               annos,
                                vis.result);
     }
 
@@ -442,7 +640,7 @@
      */
     public List<Attribute.Compound> getAllAnnotationMirrors(Element e) {
         Symbol sym = cast(Symbol.class, e);
-        List<Attribute.Compound> annos = sym.getAnnotationMirrors();
+        List<Attribute.Compound> annos = sym.getRawAttributes();
         while (sym.getKind() == ElementKind.CLASS) {
             Type sup = ((ClassSymbol) sym).getSuperclass();
             if (!sup.hasTag(CLASS) || sup.isErroneous() ||
@@ -451,7 +649,8 @@
             }
             sym = sup.tsym;
             List<Attribute.Compound> oldAnnos = annos;
-            for (Attribute.Compound anno : sym.getAnnotationMirrors()) {
+            List<Attribute.Compound> newAnnos = sym.getRawAttributes();
+            for (Attribute.Compound anno : newAnnos) {
                 if (isInherited(anno.type) &&
                         !containsAnnoOfType(oldAnnos, anno.type)) {
                     annos = annos.prepend(anno);
@@ -465,11 +664,7 @@
      * Tests whether an annotation type is @Inherited.
      */
     private boolean isInherited(Type annotype) {
-        for (Attribute.Compound anno : annotype.tsym.getAnnotationMirrors()) {
-            if (anno.type.tsym == syms.inheritedType.tsym)
-                return true;
-        }
-        return false;
+        return annotype.tsym.attribute(syms.inheritedType.tsym) != null;
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Sun Jan 20 23:39:11 2013 -0800
@@ -245,40 +245,42 @@
         token = S.token();
     }
 
-    protected boolean peekToken(TokenKind tk) {
+    protected boolean peekToken(Filter<TokenKind> tk) {
         return peekToken(0, tk);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind tk) {
-        return S.token(lookahead + 1).kind == tk;
+    protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
+        return tk.accepts(S.token(lookahead + 1).kind);
     }
 
-    protected boolean peekToken(TokenKind tk1, TokenKind tk2) {
+    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
         return peekToken(0, tk1, tk2);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) {
-        return S.token(lookahead + 1).kind == tk1 &&
-                S.token(lookahead + 2).kind == tk2;
+    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
+        return tk1.accepts(S.token(lookahead + 1).kind) &&
+                tk2.accepts(S.token(lookahead + 2).kind);
     }
 
-    protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) {
+    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
         return peekToken(0, tk1, tk2, tk3);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) {
-        return S.token(lookahead + 1).kind == tk1 &&
-                S.token(lookahead + 2).kind == tk2 &&
-                S.token(lookahead + 3).kind == tk3;
+    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
+        return tk1.accepts(S.token(lookahead + 1).kind) &&
+                tk2.accepts(S.token(lookahead + 2).kind) &&
+                tk3.accepts(S.token(lookahead + 3).kind);
     }
 
-    protected boolean peekToken(TokenKind... kinds) {
+    @SuppressWarnings("unchecked")
+    protected boolean peekToken(Filter<TokenKind>... kinds) {
         return peekToken(0, kinds);
     }
 
-    protected boolean peekToken(int lookahead, TokenKind... kinds) {
+    @SuppressWarnings("unchecked")
+    protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
         for (; lookahead < kinds.length ; lookahead++) {
-            if (S.token(lookahead + 1).kind != kinds[lookahead]) {
+            if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
                 return false;
             }
         }
@@ -333,6 +335,7 @@
                     if (stopAtMemberDecl)
                         return;
                     break;
+                case UNDERSCORE:
                 case IDENTIFIER:
                    if (stopAtIdentifier)
                         return;
@@ -552,11 +555,16 @@
                 nextToken();
                 return name;
             }
+        } else if (token.kind == UNDERSCORE) {
+            warning(token.pos, "underscore.as.identifier");
+            Name name = token.name();
+            nextToken();
+            return name;
         } else {
             accept(IDENTIFIER);
             return names.error;
         }
-}
+    }
 
     /**
      * Qualident = Ident { DOT Ident }
@@ -1056,7 +1064,7 @@
                 typeArgs = null;
             } else return illegal();
             break;
-        case IDENTIFIER: case ASSERT: case ENUM:
+        case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
             if (typeArgs != null) return illegal();
             if ((mode & EXPR) != 0 && peekToken(ARROW)) {
                 t = lambdaExpressionOrStatement(false, false, pos);
@@ -1274,7 +1282,7 @@
         int pos = 0, depth = 0;
         for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
             switch (t.kind) {
-                case IDENTIFIER: case QUES: case EXTENDS: case SUPER:
+                case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
                 case DOUBLE: case BOOLEAN: case CHAR:
@@ -1323,8 +1331,8 @@
                     if (peekToken(lookahead, RPAREN)) {
                         //Type, ')' -> cast
                         return ParensResult.CAST;
-                    } else if (peekToken(lookahead, IDENTIFIER)) {
-                        //Type, 'Identifier -> explicit lambda
+                    } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
+                        //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
                         return ParensResult.EXPLICIT_LAMBDA;
                     }
                     break;
@@ -1350,16 +1358,19 @@
                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
                         case TRUE: case FALSE: case NULL:
-                            case NEW: case IDENTIFIER: case ASSERT: case ENUM:
+                        case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
                         case BYTE: case SHORT: case CHAR: case INT:
                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
                             return ParensResult.CAST;
                         default:
                             return ParensResult.PARENS;
                     }
+                case UNDERSCORE:
+                case ASSERT:
+                case ENUM:
                 case IDENTIFIER:
-                    if (peekToken(lookahead, IDENTIFIER)) {
-                        // Identifier, Identifier -> explicit lambda
+                    if (peekToken(lookahead, LAX_IDENTIFIER)) {
+                        // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
                         return ParensResult.EXPLICIT_LAMBDA;
                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
                         // Identifier, ')' '->' -> implicit lambda
@@ -1372,8 +1383,8 @@
                     //those can only appear in explicit lambdas
                     return ParensResult.EXPLICIT_LAMBDA;
                 case LBRACKET:
-                    if (peekToken(lookahead, RBRACKET, IDENTIFIER)) {
-                        // '[', ']', Identifier -> explicit lambda
+                    if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
+                        // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
                         return ParensResult.EXPLICIT_LAMBDA;
                     } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
                             peekToken(lookahead, RBRACKET, AMP)) {
@@ -1402,11 +1413,11 @@
                             // '>', ')' -> cast
                             // '>', '&' -> cast
                             return ParensResult.CAST;
-                        } else if (peekToken(lookahead, IDENTIFIER, COMMA) ||
-                                peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) ||
+                        } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
+                                peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
                                 peekToken(lookahead, ELLIPSIS)) {
-                            // '>', Identifier, ',' -> explicit lambda
-                            // '>', Identifier, ')', '->' -> explicit lambda
+                            // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
+                            // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
                             // '>', '...' -> explicit lambda
                             return ParensResult.EXPLICIT_LAMBDA;
                         }
@@ -1426,6 +1437,13 @@
         }
     }
 
+    /** Accepts all identifier-like tokens */
+    Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
+        public boolean accepts(TokenKind t) {
+            return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
+        }
+    };
+
     enum ParensResult {
         CAST,
         EXPLICIT_LAMBDA,
@@ -1433,21 +1451,9 @@
         PARENS;
     }
 
-    JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) {
-        ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
-        params.append(firstParam);
-        JCVariableDecl lastParam = firstParam;
-        while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
-            nextToken();
-            params.append(lastParam = formalParameter());
-        }
-        accept(RPAREN);
-        return lambdaExpressionOrStatementRest(params.toList(), pos);
-    }
-
     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
         List<JCVariableDecl> params = explicitParams ?
-                formalParameters() :
+                formalParameters(true) :
                 implicitParameters(hasParens);
 
         return lambdaExpressionOrStatementRest(params, pos);
@@ -1628,7 +1634,7 @@
             nextToken();
             JCExpression bound = parseType();
             return F.at(pos).Wildcard(t, bound);
-        } else if (token.kind == IDENTIFIER) {
+        } else if (LAX_IDENTIFIER.accepts(token.kind)) {
             //error recovery
             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
@@ -1678,7 +1684,7 @@
             if (token.pos == endPosTable.errorEndPos) {
                 // error recovery
                 Name name = null;
-                if (token.kind == IDENTIFIER) {
+                if (LAX_IDENTIFIER.accepts(token.kind)) {
                     name = token.name();
                     nextToken();
                 } else {
@@ -2026,10 +2032,7 @@
                 nextToken();
                 JCStatement stat = parseStatement();
                 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
-            } else if ((lastmode & TYPE) != 0 &&
-                       (token.kind == IDENTIFIER ||
-                        token.kind == ASSERT ||
-                        token.kind == ENUM)) {
+            } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
                 pos = token.pos;
                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
                 F.at(pos);
@@ -2183,14 +2186,14 @@
         }
         case BREAK: {
             nextToken();
-            Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
+            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
             JCBreak t = to(F.at(pos).Break(label));
             accept(SEMI);
             return t;
         }
         case CONTINUE: {
             nextToken();
-            Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
+            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
             JCContinue t =  to(F.at(pos).Continue(label));
             accept(SEMI);
             return t;
@@ -2351,9 +2354,7 @@
             return variableDeclarators(optFinal(0), parseType(), stats).toList();
         } else {
             JCExpression t = term(EXPR | TYPE);
-            if ((lastmode & TYPE) != 0 &&
-                (token.kind == IDENTIFIER || token.kind == ASSERT ||
-                 token.kind == ENUM)) {
+            if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
                 return variableDeclarators(modifiersOpt(), t, stats).toList();
             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
                 error(pos, "bad.initializer", "for-loop");
@@ -2609,8 +2610,18 @@
     /** VariableDeclaratorId = Ident BracketsOpt
      */
     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
+        return variableDeclaratorId(mods, type, false);
+    }
+    //where
+    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
         int pos = token.pos;
-        Name name = ident();
+        Name name;
+        if (lambdaParameter && token.kind == UNDERSCORE) {
+            syntaxError(pos, "expected", IDENTIFIER);
+            name = token.name();
+        } else {
+            name = ident();
+        }
         if ((mods.flags & Flags.VARARGS) != 0 &&
                 token.kind == LBRACKET) {
             log.error(token.pos, "varargs.and.old.array.syntax");
@@ -2770,7 +2781,7 @@
             } else {
                 int pos = token.pos;
                 List<JCTree> errs;
-                if (token.kind == IDENTIFIER) {
+                if (LAX_IDENTIFIER.accepts(token.kind)) {
                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
                     setErrorEndPos(token.pos);
                 } else {
@@ -2787,7 +2798,7 @@
             }
             int pos = token.pos;
             List<JCTree> errs;
-            if (token.kind == IDENTIFIER) {
+            if (LAX_IDENTIFIER.accepts(token.kind)) {
                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
                 setErrorEndPos(token.pos);
             } else {
@@ -3182,14 +3193,17 @@
      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
      */
     List<JCVariableDecl> formalParameters() {
+        return formalParameters(false);
+    }
+    List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
         JCVariableDecl lastParam = null;
         accept(LPAREN);
         if (token.kind != RPAREN) {
-            params.append(lastParam = formalParameter());
+            params.append(lastParam = formalParameter(lambdaParameters));
             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
                 nextToken();
-                params.append(lastParam = formalParameter());
+                params.append(lastParam = formalParameter(lambdaParameters));
             }
         }
         accept(RPAREN);
@@ -3225,6 +3239,9 @@
      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
      */
     protected JCVariableDecl formalParameter() {
+        return formalParameter(false);
+    }
+    protected JCVariableDecl formalParameter(boolean lambdaParameter) {
         JCModifiers mods = optFinal(Flags.PARAMETER);
         JCExpression type = parseType();
         if (token.kind == ELLIPSIS) {
@@ -3233,12 +3250,12 @@
             type = to(F.at(token.pos).TypeArray(type));
             nextToken();
         }
-        return variableDeclaratorId(mods, type);
+        return variableDeclaratorId(mods, type, lambdaParameter);
     }
 
     protected JCVariableDecl implicitParameter() {
         JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
-        return variableDeclaratorId(mods, null);
+        return variableDeclaratorId(mods, null, true);
     }
 
 /* ---------- auxiliary methods -------------- */
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java	Sun Jan 20 23:39:11 2013 -0800
@@ -33,6 +33,7 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Filter;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Names;
 
@@ -74,7 +75,6 @@
     protected Tokens(Context context) {
         context.put(tokensKey, this);
         names = Names.instance(context);
-
         for (TokenKind t : TokenKind.values()) {
             if (t.name != null)
                 enterKeyword(t.name, t);
@@ -113,7 +113,7 @@
      * This enum defines all tokens used by the javac scanner. A token is
      * optionally associated with a name.
      */
-    public enum TokenKind implements Formattable {
+    public enum TokenKind implements Formattable, Filter<TokenKind> {
         EOF(),
         ERROR(),
         IDENTIFIER(Tag.NAMED),
@@ -176,6 +176,7 @@
         TRUE("true", Tag.NAMED),
         FALSE("false", Tag.NAMED),
         NULL("null", Tag.NAMED),
+        UNDERSCORE("_", Tag.NAMED),
         ARROW("->"),
         COLCOL("::"),
         LPAREN("("),
@@ -283,6 +284,11 @@
         public String toString(Locale locale, Messages messages) {
             return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
         }
+
+        @Override
+        public boolean accepts(TokenKind that) {
+            return this == that;
+        }
     }
 
     public interface Comment {
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -178,13 +178,22 @@
 compiler.misc.incompatible.abstracts=\
     multiple non-overriding abstract methods found in {0} {1}
 
-compiler.misc.not.a.functional.intf=\
-    the target type must be a functional interface
+compiler.err.bad.functional.intf.anno=\
+    Unexpected @FunctionalInterface annotation
 
 # 0: message segment
+compiler.err.bad.functional.intf.anno.1=\
+    Unexpected @FunctionalInterface annotation\n\
+    {0}
+
+# 0: symbol
+compiler.misc.not.a.functional.intf=\
+    {0} is not a functional interface
+
+# 0: symbol, 1: message segment
 compiler.misc.not.a.functional.intf.1=\
-    the target type must be a functional interface\n\
-    {0}
+    {0} is not a functional interface\n\
+    {1}
 
 # 0: symbol, 1: symbol kind, 2: symbol
 compiler.misc.invalid.generic.lambda.target=\
@@ -319,64 +328,48 @@
 compiler.err.duplicate.annotation.missing.container=\
     duplicate annotation, the declaration of {0} does not have a valid {1} annotation
 
-# 0: type, 1: type
-compiler.err.invalid.container.no.containedby=\
-    invalid contained repeatable annotation, {0} is not annotated with {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.wrong.containedby=\
-    invalid contained repeatable annotation, {0} does not match {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.no.containerfor=\
-    invalid container for repeating annotations, {0} is not annotated with {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.wrong.containerfor=\
-    invalid container for repeating annotations, {0} does not match {1}
+# 0: type
+compiler.err.invalid.repeatable.annotation=\
+    duplicate annotation, {0} is annotated with an invalid Repeatable annotation
 
 # 0: type
-compiler.err.invalid.containedby.annotation=\
-    duplicate annotation, {0} is annotated with an invalid ContainedBy annotation
-
-# 0: type
-compiler.err.invalid.containedby.annotation.no.value=\
-    duplicate annotation, {0} is not a valid ContainedBy, no value element method declared
+compiler.err.invalid.repeatable.annotation.no.value=\
+    duplicate annotation, {0} is not a valid Repeatable, no value element method declared
 
 # 0: type, 1: number
-compiler.err.invalid.containedby.annotation.multiple.values=\
-    duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared
+compiler.err.invalid.repeatable.annotation.multiple.values=\
+    duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared
 
 # 0: type
-compiler.err.invalid.containedby.annotation.invalid.value=\
-    duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method
+compiler.err.invalid.repeatable.annotation.invalid.value=\
+    duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method
 
 # 0: type, 1: type, 2: type
-compiler.err.invalid.containedby.annotation.value.return=\
+compiler.err.invalid.repeatable.annotation.value.return=\
     duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
 
 # 0: type, 1: symbol
-compiler.err.invalid.containedby.annotation.elem.nondefault=\
+compiler.err.invalid.repeatable.annotation.elem.nondefault=\
     containing annotation {0} does not have a default value for element {1}
 
 # 0: symbol, 1: type, 2: symbol, 3: type
-compiler.err.invalid.containedby.annotation.retention=\
+compiler.err.invalid.repeatable.annotation.retention=\
     containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
 
 # 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.not.documented=\
+compiler.err.invalid.repeatable.annotation.not.documented=\
     containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
 
 # 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.not.inherited=\
+compiler.err.invalid.repeatable.annotation.not.inherited=\
     containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
 
 # 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.incompatible.target=\
+compiler.err.invalid.repeatable.annotation.incompatible.target=\
     target of container annotation {0} is not a subset of target of repeated annotation {1}
 
 # 0: symbol
-compiler.err.invalid.containedby.annotation.repeated.and.container.present=\
+compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\
     container {0} must not be present at the same time as the element it contains
 
 # 0: name
@@ -2139,6 +2132,10 @@
     as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\
     (use -source 1.4 or higher to use ''assert'' as a keyword)
 
+compiler.warn.underscore.as.identifier=\
+    ''_'' used as an identifier\n\
+    (use of ''_'' as an identifier might not be supported in future releases)
+
 compiler.err.enum.as.identifier=\
     as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
     (use -source 1.4 or lower to use ''enum'' as an identifier)
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1838,7 +1838,9 @@
             /** Inner # new */
             IMPLICIT_INNER(ReferenceMode.NEW, false),
             /** Toplevel # new */
-            TOPLEVEL(ReferenceMode.NEW, false);
+            TOPLEVEL(ReferenceMode.NEW, false),
+            /** ArrayType # new */
+            ARRAY_CTOR(ReferenceMode.NEW, false);
 
             final ReferenceMode mode;
             final boolean unbound;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Sun Jan 20 23:39:11 2013 -0800
@@ -288,7 +288,7 @@
 
         public String simplify(Symbol s) {
             String name = s.getQualifiedName().toString();
-            if (!s.type.isCompound()) {
+            if (!s.type.isCompound() && !s.type.isPrimitive()) {
                 List<Symbol> conflicts = nameClashes.get(s.getSimpleName());
                 if (conflicts == null ||
                     (conflicts.size() == 1 &&
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,10 @@
 import javax.tools.JavaFileManager;
 
 import com.sun.javadoc.*;
+import com.sun.source.util.JavacTask;
 import com.sun.source.util.TreePath;
-import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.javac.api.BasicJavacTask;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.ClassType;
@@ -105,6 +107,7 @@
     Types types;
     JavaFileManager fileManager;
     Context context;
+    DocLint doclint;
 
     WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<JCTree, TreePath>();
 
@@ -400,6 +403,9 @@
     public void warning(DocImpl doc, String key, String a1) {
         if (silent)
             return;
+        // suppress messages that have (probably) been covered by doclint
+        if (doclint != null && doc != null && key.startsWith("tag"))
+            return;
         messager.warning(doc==null ? null : doc.position(), key, a1);
     }
 
@@ -732,9 +738,15 @@
         return p;
     }
 
-    TreePath getTreePath(JCCompilationUnit toplevel, JCTree tree) {
-        // don't bother to cache paths for classes and members
-        return new TreePath(getTreePath(toplevel), tree);
+    TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) {
+        TreePath p = treePaths.get(tree);
+        if (p == null)
+            treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree));
+        return p;
+    }
+
+    TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree) {
+        return new TreePath(getTreePath(toplevel, cdecl), tree);
     }
 
     /**
@@ -781,4 +793,25 @@
             result |= Modifier.VOLATILE;
         return result;
     }
+
+    void initDoclint(Collection<String> opts) {
+        ArrayList<String> doclintOpts = new ArrayList<String>();
+
+        for (String opt: opts) {
+            doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt);
+        }
+
+        if (doclintOpts.size() == 1
+                && doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) {
+            return;
+        }
+
+        JavacTask t = BasicJavacTask.instance(context);
+        doclint = new DocLint();
+        doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
+    }
+
+    boolean showTagMessages() {
+        return (doclint == null);
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -126,7 +126,13 @@
      */
     Comment comment() {
         if (comment == null) {
-            comment = new Comment(this, documentation());
+            String d = documentation();
+            if (env.doclint != null
+                    && treePath != null
+                    && d.equals(getCommentText(treePath))) {
+                env.doclint.scan(treePath);
+            }
+            comment = new Comment(this, d);
         }
         return comment;
     }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,7 @@
         super.visitMethodDef(tree);
         MethodSymbol meth = tree.sym;
         if (meth == null || meth.kind != Kinds.MTH) return;
-        TreePath treePath = docenv.getTreePath(env.toplevel, tree);
+        TreePath treePath = docenv.getTreePath(env.toplevel, env.enclClass, tree);
         if (meth.isConstructor())
             docenv.makeConstructorDoc(meth, treePath);
         else if (isAnnotationTypeElement(meth))
@@ -90,7 +90,7 @@
         if (tree.sym != null &&
                 tree.sym.kind == Kinds.VAR &&
                 !isParameter(tree.sym)) {
-            docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, tree));
+            docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, env.enclClass, tree));
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,13 +26,14 @@
 package com.sun.tools.javadoc;
 
 import java.io.IOException;
+import java.util.Collection;
 import java.util.Locale;
+
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 
 import com.sun.javadoc.*;
-
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
@@ -375,4 +376,12 @@
     public JavaFileManager getFileManager() {
         return env.fileManager;
     }
+
+    public void initDocLint(Collection<String> opts) {
+        env.initDoclint(opts);
+    }
+
+    public boolean showTagMessages() {
+        return env.showTagMessages();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The build state class captures the source code and generated artifacts
+ * from a build. There are usually two build states, the previous one (prev),
+ * loaded from the javac_state file, and the current one (now).
+ *
+ * <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></p>
+ */
+public class BuildState {
+    private Map<String,Module> modules = new HashMap<String,Module>();
+    private Map<String,Package> packages = new HashMap<String,Package>();
+    private Map<String,Source> sources = new HashMap<String,Source>();
+    private Map<String,File> artifacts = new HashMap<String,File>();
+    // Map from package to a set of packages that depend on said package.
+    private Map<String,Set<String>> dependents = new HashMap<String,Set<String>>();
+
+    public  Map<String,Module> modules() { return modules; }
+    public  Map<String,Package> packages() { return packages; }
+    public  Map<String,Source> sources() { return sources; }
+    public  Map<String,File> artifacts() { return artifacts; }
+    public  Map<String,Set<String>> dependents() { return dependents; }
+
+    /**
+     * Lookup a module from a name. Create the module if it does
+     * not exist yet.
+     */
+    public Module lookupModule(String mod) {
+        Module m = modules.get(mod);
+        if (m == null) {
+            m = new Module(mod, "???");
+            modules.put(mod, m);
+        }
+        return m;
+    }
+
+    /**
+     * Find a module from a given package name. For example:
+     * The package name "base:java.lang" will fetch the module named "base".
+     * The package name ":java.net" will fetch the default module.
+     */
+    Module findModuleFromPackageName(String pkg) {
+        int cp = pkg.indexOf(':');
+        assert(cp != -1);
+        String mod = pkg.substring(0, cp);
+        return lookupModule(mod);
+    }
+
+    /**
+     * Collect all packages, sources and artifacts for all modules
+     * into the build state.
+     *
+     * @param m The set of modules.
+     */
+    public void collectPackagesSourcesAndArtifacts(Map<String,Module> m) {
+        modules = m;
+        // Extract all the found packages.
+        for (Module i : modules.values()) {
+            for (Map.Entry<String,Package> j : i.packages().entrySet()) {
+                Package p = packages.get(j.getKey());
+                // Check that no two different packages are stored under same name.
+                assert(p == null || p == j.getValue());
+                if (p == null) {
+                    p = j.getValue();
+                    packages.put(j.getKey(),j.getValue());
+                }
+                for (Map.Entry<String,Source> k : p.sources().entrySet()) {
+                    Source s = sources.get(k.getKey());
+                    // Check that no two different sources are stored under same name.
+                    assert(s == null || s == k.getValue());
+                    if (s == null) {
+                        s = k.getValue();
+                        sources.put(k.getKey(), k.getValue());
+                    }
+                }
+                for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
+                    File f = artifacts.get(g.getKey());
+                    // Check that no two artifacts are stored under the same file.
+                    assert(f == null || f == g.getValue());
+                    if (f == null) {
+                        f = g.getValue();
+                        artifacts.put(g.getKey(), g.getValue());
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Collect all the artifacts of all modules and packages.
+     *
+     * @param m The set of modules.
+     */
+    public void collectArtifacts(Map<String,Module> m) {
+        modules = m;
+        // Extract all the found packages.
+        for (Module i : modules.values()) {
+            for (Map.Entry<String,Package> j : i.packages().entrySet()) {
+                Package p = packages.get(j.getKey());
+                // Check that no two different packages are stored under same name.
+                assert(p == null || p == j.getValue());
+                p = j.getValue();
+                packages.put(j.getKey(),j.getValue());
+                for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
+                    File f = artifacts.get(g.getKey());
+                    // Check that no two artifacts are stored under the same file.
+                    assert(f == null || f == g.getValue());
+                    artifacts.put(g.getKey(), g.getValue());
+                }
+            }
+        }
+    }
+
+    /**
+     * Calculate the package dependents (ie the reverse of the dependencies).
+     */
+    public void calculateDependents() {
+        dependents = new HashMap<String,Set<String>>();
+        for (String s : packages.keySet()) {
+            Package p = packages.get(s);
+            for (String d : p.dependencies()) {
+                Set<String> ss = dependents.get(d);
+                if (ss == null) {
+                    ss = new HashSet<String>();
+                    dependents.put(d, ss);
+                }
+                // Add the dependent information to the global dependent map.
+                ss.add(s);
+                Package dp = packages.get(d);
+                // Also add the dependent information to the package specific map.
+                // Normally, you do not compile java.lang et al. Therefore
+                // there are several packages that p depends upon that you
+                // do not have in your state database. This is perfectly fine.
+                if (dp != null) {
+                    // But this package did exist in the state database.
+                    dp.addDependent(p.name());
+                }
+            }
+        }
+    }
+
+    /**
+     * Verify that the setModules method above did the right thing when
+     * running through the module->package->source structure.
+     */
+    public void checkInternalState(String msg, boolean linkedOnly, Map<String,Source> srcs) {
+        boolean baad = false;
+        Map<String,Source> original = new HashMap<String,Source>();
+        Map<String,Source> calculated = new HashMap<String,Source>();
+
+        for (String s : sources.keySet()) {
+            Source ss = sources.get(s);
+            if (ss.isLinkedOnly() == linkedOnly) {
+                calculated.put(s,ss);
+            }
+        }
+        for (String s : srcs.keySet()) {
+            Source ss = srcs.get(s);
+            if (ss.isLinkedOnly() == linkedOnly) {
+                original.put(s,ss);
+            }
+        }
+        if (original.size() != calculated.size()) {
+            Log.error("INTERNAL ERROR "+msg+" original and calculated are not the same size!");
+            baad = true;
+        }
+        if (!original.keySet().equals(calculated.keySet())) {
+            Log.error("INTERNAL ERROR "+msg+" original and calculated do not have the same domain!");
+            baad = true;
+        }
+        if (!baad) {
+            for (String s : original.keySet()) {
+                Source s1 = original.get(s);
+                Source s2 = calculated.get(s);
+                if (s1 == null || s2 == null || !s1.equals(s2)) {
+                    Log.error("INTERNAL ERROR "+msg+" original and calculated have differing elements for "+s);
+                }
+                baad = true;
+            }
+        }
+        if (baad) {
+            for (String s : original.keySet()) {
+                Source ss = original.get(s);
+                Source sss = calculated.get(s);
+                if (sss == null) {
+                    Log.error("The file "+s+" does not exist in calculated tree of sources.");
+                }
+            }
+            for (String s : calculated.keySet()) {
+                Source ss = calculated.get(s);
+                Source sss = original.get(s);
+                if (sss == null) {
+                    Log.error("The file "+s+" does not exist in original set of found sources.");
+                }
+            }
+        }
+    }
+
+    /**
+     * Load a module from the javac state file.
+     */
+    public Module loadModule(String l) {
+        Module m = Module.load(l);
+        modules.put(m.name(), m);
+        return m;
+    }
+
+    /**
+     * Load a package from the javac state file.
+     */
+    public Package loadPackage(Module lastModule, String l) {
+        Package p = Package.load(lastModule, l);
+        lastModule.addPackage(p);
+        packages.put(p.name(), p);
+        return p;
+    }
+
+    /**
+     * Load a source from the javac state file.
+     */
+    public Source loadSource(Package lastPackage, String l, boolean is_generated) {
+        Source s = Source.load(lastPackage, l, is_generated);
+        lastPackage.addSource(s);
+        sources.put(s.name(), s);
+        return s;
+    }
+
+    /**
+     * During an incremental compile we need to copy the old javac state
+     * information about packages that were not recompiled.
+     */
+    public void copyPackagesExcept(BuildState prev, Set<String> recompiled, Set<String> removed) {
+        for (String pkg : prev.packages().keySet()) {
+            // Do not copy recompiled or removed packages.
+            if (recompiled.contains(pkg) || removed.contains(pkg)) continue;
+            Module mnew = findModuleFromPackageName(pkg);
+            Package pprev = prev.packages().get(pkg);
+            mnew.addPackage(pprev);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * The clean properties transform should not be necessary.
+ * Eventually we will cleanup the property file sources in the OpenJDK instead.
+ *
+ * <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></p>
+ */
+public class CleanProperties implements Transformer
+{
+    public void setExtra(String e) {
+        // Any extra information is ignored for clean properties.
+    }
+
+    public void setExtra(String[] a) {
+        // Any extra information is ignored for clean properties.
+    }
+
+    public boolean transform(Map<String,Set<URI>> pkgSrcs,
+                             Set<URI>             visibleSrcs,
+                             Map<URI,Set<String>> visibleClasses,
+                             Map<String,Set<String>> oldPackageDependencies,
+                             URI destRoot,
+                             Map<String,Set<URI>>    packageArtifacts,
+                             Map<String,Set<String>> packageDependencies,
+                             Map<String,String>      packagePublicApis,
+                             int debugLevel,
+                             boolean incremental,
+                             int numCores,
+                             PrintStream out,
+                             PrintStream err)
+    {
+        boolean rc = true;
+        for (String pkgName : pkgSrcs.keySet()) {
+            String pkgNameF = pkgName.replace('.',File.separatorChar);
+            for (URI u : pkgSrcs.get(pkgName)) {
+                File src = new File(u);
+                boolean r = clean(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
+                                  packageArtifacts);
+                if (r == false) {
+                    rc = false;
+                }
+            }
+        }
+        return rc;
+    }
+
+    boolean clean(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
+                  Map<String,Set<URI>> packageArtifacts)
+    {
+        // Load the properties file.
+        Properties p = new Properties();
+        try {
+            p.load(new FileInputStream(src));
+        } catch (IOException e) {
+            Log.error("Error reading file "+src.getPath());
+            return false;
+        }
+
+        // Sort the properties in increasing key order.
+        List<String> sortedKeys = new ArrayList<String>();
+        for (Object key : p.keySet()) {
+            sortedKeys.add((String)key);
+        }
+        Collections.sort(sortedKeys);
+        Iterator<String> keys = sortedKeys.iterator();
+
+        // Collect the properties into a string buffer.
+        StringBuilder data = new StringBuilder();
+        while (keys.hasNext()) {
+            String key = keys.next();
+            data.append(CompileProperties.escape(key)+":"+CompileProperties.escape((String)p.get(key))+"\n");
+        }
+
+        String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
+        File dest = new File(destFilename);
+
+        // Make sure the dest directories exist.
+        if (!dest.getParentFile().isDirectory()) {
+            if (!dest.getParentFile().mkdirs()) {
+                Log.error("Could not create the directory "+dest.getParentFile().getPath());
+                return false;
+            }
+        }
+
+        Set<URI> as = packageArtifacts.get(pkgName);
+        if (as == null) {
+            as = new HashSet<URI>();
+            packageArtifacts.put(pkgName, as);
+        }
+        as.add(dest.toURI());
+
+        if (dest.exists() && dest.lastModified() > src.lastModified()) {
+            // A cleaned property file exists, and its timestamp is newer than the source.
+            // Assume that we do not need to clean!
+            // Thus we are done.
+            return true;
+        }
+
+        Log.info("Cleaning property file "+pkgNameF+File.separator+src.getName());
+        try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
+            writer.write(data.toString());
+        } catch ( IOException e ) {
+            Log.error("Could not write file "+dest.getPath());
+            return false;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileChunk.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A compile chunk is a list of sources/packages to be compiled. Possibly a subset of
+ * the total number of sources/packages to be compiled for this sjavac invocation.
+ *
+ * <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></p>
+ */
+public class CompileChunk implements Comparable<CompileChunk> {
+    public int numPackages;
+    public int numDependents;
+    public Set<URI> srcs = new HashSet<URI>();
+    public StringBuilder pkgNames = new StringBuilder();
+    public String pkgFromTos = "";
+
+    public int compareTo(CompileChunk c) {
+        if (numDependents == c.numDependents) return 0;
+        if (numDependents > c.numDependents) return -1;
+        return -1;
+    }
+
+    boolean equal(CompileChunk c) {
+        return numDependents == c.numDependents;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.Set;
+import java.util.Map;
+
+import com.sun.tools.sjavac.server.JavacServer;
+import com.sun.tools.sjavac.server.SysInfo;
+import java.io.PrintStream;
+
+/**
+ * This transform compiles a set of packages containing Java sources.
+ * The compile request is divided into separate sets of source files.
+ * For each set a separate request thread is dispatched to a javac server
+ * and the meta data is accumulated. The number of sets correspond more or
+ * less to the number of cores. Less so now, than it will in the future.
+ *
+ * <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></p>
+ */
+public class CompileJavaPackages implements Transformer {
+
+    // The current limited sharing of data between concurrent JavaCompilers
+    // in the server will not give speedups above 3 cores. Thus this limit.
+    // We hope to improve this in the future.
+    final static int limitOnConcurrency = 3;
+
+    String serverSettings;
+    public void setExtra(String e) {
+        serverSettings = e;
+    }
+
+    String[] args;
+    public void setExtra(String[] a) {
+        args = a;
+    }
+
+    public boolean transform(Map<String,Set<URI>> pkgSrcs,
+                             Set<URI>             visibleSources,
+                             Map<URI,Set<String>> visibleClasses,
+                             Map<String,Set<String>> oldPackageDependents,
+                             URI destRoot,
+                             final Map<String,Set<URI>>    packageArtifacts,
+                             final Map<String,Set<String>> packageDependencies,
+                             final Map<String,String>      packagePubapis,
+                             int debugLevel,
+                             boolean incremental,
+                             int numCores,
+                             PrintStream out,
+                             PrintStream err)
+    {
+        boolean rc = true;
+        boolean concurrentCompiles = true;
+
+        // Fetch the id.
+        String id = Util.extractStringOption("id", serverSettings);
+        if (id == null || id.equals("")) {
+            // No explicit id set. Create a random id so that the requests can be
+            // grouped properly in the server.
+            id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
+        }
+        // Only keep portfile and sjavac settings..
+        String psServerSettings = Util.cleanSubOptions("--server:", Util.set("portfile","sjavac","background","keepalive"), serverSettings);
+
+        // Get maximum heap size from the server!
+        SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err);
+        if (sysinfo.numCores == -1) {
+            Log.error("Could not query server for sysinfo!");
+            return false;
+        }
+        int numMBytes = (int)(sysinfo.maxMemory / ((long)(1024*1024)));
+        Log.debug("Server reports "+numMBytes+"MiB of memory and "+sysinfo.numCores+" cores");
+
+        if (numCores <= 0) {
+            // Set the requested number of cores to the number of cores on the server.
+            numCores = sysinfo.numCores;
+            Log.debug("Number of jobs not explicitly set, defaulting to "+sysinfo.numCores);
+        } else if (sysinfo.numCores < numCores) {
+            // Set the requested number of cores to the number of cores on the server.
+            Log.debug("Limiting jobs from explicitly set "+numCores+" to cores available on server: "+sysinfo.numCores);
+            numCores = sysinfo.numCores;
+        } else {
+            Log.debug("Number of jobs explicitly set to "+numCores);
+        }
+        // More than three concurrent cores does not currently give a speedup, at least for compiling the jdk
+        // in the OpenJDK. This will change in the future.
+        int numCompiles = numCores;
+        if (numCores > limitOnConcurrency) numCompiles = limitOnConcurrency;
+        // Split the work up in chunks to compiled.
+
+        int numSources = 0;
+        for (String s : pkgSrcs.keySet()) {
+            Set<URI> ss = pkgSrcs.get(s);
+            numSources += ss.size();
+        }
+
+        int sourcesPerCompile = numSources / numCompiles;
+
+        // For 64 bit Java, it seems we can compile the OpenJDK 8800 files with a 1500M of heap
+        // in a single chunk, with reasonable performance.
+        // For 32 bit java, it seems we need 1G of heap.
+        // Number experimentally determined when compiling the OpenJDK.
+        // Includes space for reasonably efficient garbage collection etc,
+        // Calculating backwards gives us a requirement of
+        // 1500M/8800 = 175 KiB for 64 bit platforms
+        // and 1G/8800 = 119 KiB for 32 bit platform
+        // for each compile.....
+        int kbPerFile = 175;
+        String osarch = System.getProperty("os.arch");
+        if (osarch.equals("i386")) {
+            // For 32 bit platforms, assume it is slightly smaller
+            // because of smaller object headers and pointers.
+            kbPerFile = 119;
+        }
+        int numRequiredMBytes = (kbPerFile*numSources)/1024;
+        Log.debug("For os.arch "+osarch+" the empirically determined heap required per file is "+kbPerFile+"KiB");
+        Log.debug("Server has "+numMBytes+"MiB of heap.");
+        Log.debug("Heuristics say that we need "+numRequiredMBytes+"MiB of heap for all source files.");
+        // Perform heuristics to see how many cores we can use,
+        // or if we have to the work serially in smaller chunks.
+        if (numMBytes < numRequiredMBytes) {
+            // Ouch, cannot fit even a single compile into the heap.
+            // Split it up into several serial chunks.
+            concurrentCompiles = false;
+            // Limit the number of sources for each compile to 500.
+            if (numSources < 500) {
+                numCompiles = 1;
+                sourcesPerCompile = numSources;
+                Log.debug("Compiling as a single source code chunk to stay within heap size limitations!");
+            } else if (sourcesPerCompile > 500) {
+                // This number is very low, and tuned to dealing with the OpenJDK
+                // where the source is >very< circular! In normal application,
+                // with less circularity the number could perhaps be increased.
+                numCompiles = numSources / 500;
+                sourcesPerCompile = numSources/numCompiles;
+                Log.debug("Compiling source as "+numCompiles+" code chunks serially to stay within heap size limitations!");
+            }
+        } else {
+            if (numCompiles > 1) {
+                // Ok, we can fit at least one full compilation on the heap.
+                float usagePerCompile = (float)numRequiredMBytes / ((float)numCompiles * (float)0.7);
+                int usage = (int)(usagePerCompile * (float)numCompiles);
+                Log.debug("Heuristics say that for "+numCompiles+" concurrent compiles we need "+usage+"MiB");
+                if (usage > numMBytes) {
+                    // Ouch it does not fit. Reduce to a single chunk.
+                    numCompiles = 1;
+                    sourcesPerCompile = numSources;
+                    // What if the relationship betweem number of compile_chunks and num_required_mbytes
+                    // is not linear? Then perhaps 2 chunks would fit where 3 does not. Well, this is
+                    // something to experiment upon in the future.
+                    Log.debug("Limiting compile to a single thread to stay within heap size limitations!");
+                }
+            }
+        }
+
+        Log.debug("Compiling sources in "+numCompiles+" chunk(s)");
+
+        // Create the chunks to be compiled.
+        final CompileChunk[] compileChunks = createCompileChunks(pkgSrcs, oldPackageDependents,
+                numCompiles, sourcesPerCompile);
+
+        if (Log.isDebugging()) {
+            int cn = 1;
+            for (CompileChunk cc : compileChunks) {
+                Log.debug("Chunk "+cn+" for "+id+" ---------------");
+                cn++;
+                for (URI u : cc.srcs) {
+                    Log.debug(""+u);
+                }
+            }
+        }
+
+        // The return values for each chunked compile.
+        final int[] rn = new int[numCompiles];
+        // The requets, might or might not run as a background thread.
+        final Thread[] requests  = new Thread[numCompiles];
+
+        final Set<URI>             fvisible_sources = visibleSources;
+        final Map<URI,Set<String>> fvisible_classes = visibleClasses;
+
+        long start = System.currentTimeMillis();
+
+        for (int i=0; i<numCompiles; ++i) {
+            final int ii = i;
+            final CompileChunk cc = compileChunks[i];
+
+            // Pass the num_cores and the id (appended with the chunk number) to the server.
+            final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+ii;
+            final PrintStream fout = out;
+            final PrintStream ferr = err;
+
+            requests[ii] = new Thread() {
+                @Override
+                public void run() {
+                                        rn[ii] = JavacServer.useServer(cleanedServerSettings,
+                                                           Main.removeWrapperArgs(args),
+                                                               cc.srcs,
+                                                           fvisible_sources,
+                                                           fvisible_classes,
+                                                           packageArtifacts,
+                                                           packageDependencies,
+                                                           packagePubapis,
+                                                           null,
+                                                           fout, ferr);
+                }
+            };
+
+            if (cc.srcs.size() > 0) {
+                String numdeps = "";
+                if (cc.numDependents > 0) numdeps = "(with "+cc.numDependents+" dependents) ";
+                if (!incremental || cc.numPackages > 16) {
+                    String info = "("+cc.pkgFromTos+")";
+                    if (info.equals("( to )")) {
+                        info = "";
+                    }
+                    Log.info("Compiling "+cc.srcs.size()+" files "+numdeps+"in "+cc.numPackages+" packages "+info);
+                } else {
+                    Log.info("Compiling "+cc.pkgNames+numdeps);
+                }
+                if (concurrentCompiles) {
+                    requests[ii].start();
+                }
+                else {
+                    requests[ii].run();
+                    // If there was an error, then stop early when running single threaded.
+                    if (rn[i] != 0) {
+                        return false;
+                    }
+                }
+            }
+        }
+        if (concurrentCompiles) {
+            // If there are background threads for the concurrent compiles, then join them.
+            for (int i=0; i<numCompiles; ++i) {
+                try { requests[i].join(); } catch (InterruptedException e) { }
+            }
+        }
+
+        // Check the return values.
+        for (int i=0; i<numCompiles; ++i) {
+            if (compileChunks[i].srcs.size() > 0) {
+                if (rn[i] != 0) {
+                    rc = false;
+                }
+            }
+        }
+        long duration = System.currentTimeMillis() - start;
+        long minutes = duration/60000;
+        long seconds = (duration-minutes*60000)/1000;
+        Log.debug("Compilation of "+numSources+" source files took "+minutes+"m "+seconds+"s");
+
+        return rc;
+    }
+
+
+    /**
+     * Split up the sources into compile chunks. If old package dependents information
+     * is available, sort the order of the chunks into the most dependent first!
+     * (Typically that chunk contains the java.lang package.) In the future
+     * we could perhaps improve the heuristics to put the sources into even more sensible chunks.
+     * Now the package are simple sorted in alphabetical order and chunked, then the chunks
+     * are sorted on how dependent they are.
+     *
+     * @param pkgSrcs The sources to compile.
+     * @param oldPackageDependents Old package dependents, if non-empty, used to sort the chunks.
+     * @param numCompiles The number of chunks.
+     * @param sourcesPerCompile The number of sources per chunk.
+     * @return
+     */
+    CompileChunk[] createCompileChunks(Map<String,Set<URI>> pkgSrcs,
+                                 Map<String,Set<String>> oldPackageDependents,
+                                 int numCompiles,
+                                 int sourcesPerCompile) {
+
+        CompileChunk[] compileChunks = new CompileChunk[numCompiles];
+        for (int i=0; i<compileChunks.length; ++i) {
+            compileChunks[i] = new CompileChunk();
+        }
+
+        // Now go through the packages and spread out the source on the different chunks.
+        int ci = 0;
+        // Sort the packages
+        String[] packageNames = pkgSrcs.keySet().toArray(new String[0]);
+        Arrays.sort(packageNames);
+        String from = null;
+        for (String pkgName : packageNames) {
+            CompileChunk cc = compileChunks[ci];
+            Set<URI> s = pkgSrcs.get(pkgName);
+            if (cc.srcs.size()+s.size() > sourcesPerCompile && ci < numCompiles-1) {
+                from = null;
+                ci++;
+                cc = compileChunks[ci];
+            }
+            cc.numPackages++;
+            cc.srcs.addAll(s);
+
+            // Calculate nice package names to use as information when compiling.
+            String justPkgName = Util.justPackageName(pkgName);
+            // Fetch how many packages depend on this package from the old build state.
+            Set<String> ss = oldPackageDependents.get(pkgName);
+            if (ss != null) {
+                // Accumulate this information onto this chunk.
+                cc.numDependents += ss.size();
+            }
+            if (from == null || from.trim().equals("")) from = justPkgName;
+            cc.pkgNames.append(justPkgName+"("+s.size()+") ");
+            cc.pkgFromTos = from+" to "+justPkgName;
+        }
+        // If we are compiling serially, sort the chunks, so that the chunk (with the most dependents) (usually the chunk
+        // containing java.lang.Object, is to be compiled first!
+        // For concurrent compilation, this does not matter.
+        Arrays.sort(compileChunks);
+        return compileChunks;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Compile properties transform a properties file into a Java source file.
+ * Java has built in support for reading properties from either a text file
+ * in the source or a compiled java source file.
+ *
+ * <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></p>
+ */
+public class CompileProperties implements Transformer
+{
+    // Any extra information passed from the command line, for example if:
+    // -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
+    // then extra will be "sun.util.resources.LocaleNamesBundle"
+    String extra;
+
+    public void setExtra(String e) {
+        extra = e;
+    }
+
+    public void setExtra(String[] a) {
+    }
+
+    public boolean transform(Map<String,Set<URI>> pkgSrcs,
+                             Set<URI>             visibleSrcs,
+                             Map<URI,Set<String>> visibleClasses,
+                             Map<String,Set<String>> oldPackageDependents,
+                             URI destRoot,
+                             Map<String,Set<URI>>    packageArtifacts,
+                             Map<String,Set<String>> packageDependencies,
+                             Map<String,String>      packagePublicApis,
+                             int debugLevel,
+                             boolean incremental,
+                             int numCores,
+                             PrintStream out,
+                             PrintStream err) {
+        boolean rc = true;
+        for (String pkgName : pkgSrcs.keySet()) {
+            String pkgNameF = Util.toFileSystemPath(pkgName);
+            for (URI u : pkgSrcs.get(pkgName)) {
+                File src = new File(u);
+                boolean r = compile(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
+                                    packageArtifacts);
+                if (r == false) {
+                    rc = false;
+                }
+            }
+        }
+        return rc;
+    }
+
+    boolean compile(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
+                    Map<String,Set<URI>> packageArtifacts)
+    {
+        String superClass = "java.util.ListResourceBundle";
+
+        if (extra != null) {
+            superClass = extra;
+        }
+        // Load the properties file.
+        Properties p = new Properties();
+        try {
+            p.load(new FileInputStream(src));
+        } catch (IOException e) {
+            Log.error("Error reading file "+src.getPath());
+            return false;
+        }
+
+        // Calculate the name of the Java source file to be generated.
+        int dp = src.getName().lastIndexOf(".");
+        String classname = src.getName().substring(0,dp);
+
+        // Sort the properties in increasing key order.
+        List<String> sortedKeys = new ArrayList<String>();
+        for (Object key : p.keySet()) {
+            sortedKeys.add((String)key);
+        }
+        Collections.sort(sortedKeys);
+        Iterator<String> keys = sortedKeys.iterator();
+
+        // Collect the properties into a string buffer.
+        StringBuilder data = new StringBuilder();
+        while (keys.hasNext()) {
+            String key = keys.next();
+            data.append("            { \"" + escape(key) + "\", \"" +
+                        escape((String)p.get(key)) + "\" },\n");
+        }
+
+        // Create dest file name. It is derived from the properties file name.
+        String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+classname+".java";
+        File dest = new File(destFilename);
+
+        // Make sure the dest directories exist.
+        if (!dest.getParentFile().isDirectory()) {
+            if (!dest.getParentFile().mkdirs()) {
+                Log.error("Could not create the directory "+dest.getParentFile().getPath());
+                return false;
+            }
+        }
+
+        Set<URI> as = packageArtifacts.get(pkgName);
+        if (as == null) {
+            as = new HashSet<URI>();
+            packageArtifacts.put(pkgName, as);
+        }
+        as.add(dest.toURI());
+
+        if (dest.exists() && dest.lastModified() > src.lastModified()) {
+            // A generated file exists, and its timestamp is newer than the source.
+            // Assume that we do not need to regenerate the dest file!
+            // Thus we are done.
+            return true;
+        }
+
+        String packageString = "package " + pkgNameF.replace(File.separatorChar,'.') + ";\n\n";
+
+        Log.info("Compiling property file "+pkgNameF+File.separator+src.getName());
+        try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
+            MessageFormat format = new MessageFormat(FORMAT);
+            writer.write(format.format(new Object[] { packageString, classname, superClass, data }));
+        } catch ( IOException e ) {
+            Log.error("Could not write file "+dest.getPath());
+            return false;
+        }
+        return true;
+    }
+
+    private static final String FORMAT =
+            "{0}" +
+            "public final class {1} extends {2} '{'\n" +
+            "    protected final Object[][] getContents() '{'\n" +
+            "        return new Object[][] '{'\n" +
+            "{3}" +
+            "        };\n" +
+            "    }\n" +
+            "}\n";
+
+    public static String escape(String theString) {
+        int len = theString.length();
+        StringBuilder outBuffer = new StringBuilder(len*2);
+
+        for(int x=0; x<len; x++) {
+            char aChar = theString.charAt(x);
+            switch(aChar) {
+                case '\\':outBuffer.append('\\'); outBuffer.append('\\');
+                break;
+                case '\t':outBuffer.append('\\'); outBuffer.append('t');
+                break;
+                case '\n':outBuffer.append('\\'); outBuffer.append('n');
+                break;
+                case '\r':outBuffer.append('\\'); outBuffer.append('r');
+                break;
+                case '\f':outBuffer.append('\\'); outBuffer.append('f');
+                break;
+                default:
+                    if ((aChar < 0x0020) || (aChar > 0x007e)) {
+                        outBuffer.append('\\');
+                        outBuffer.append('u');
+                        outBuffer.append(toHex((aChar >> 12) & 0xF));
+                        outBuffer.append(toHex((aChar >>  8) & 0xF));
+                        outBuffer.append(toHex((aChar >>  4) & 0xF));
+                        outBuffer.append(toHex( aChar        & 0xF));
+                    } else {
+                        if (aChar == '"') {
+                            outBuffer.append('\\');
+                        }
+                        outBuffer.append(aChar);
+                    }
+            }
+        }
+        return outBuffer.toString();
+    }
+
+    private static char toHex(int nibble) {
+        return hexDigit[(nibble & 0xF)];
+    }
+
+    private static final char[] hexDigit = {
+        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * The copy file transform simply copies a matching file from -src to -d .
+ * Such files are typically images, xml documents and other data files.
+ *
+ * <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></p>
+ */
+public class CopyFile implements Transformer {
+
+    public void setExtra(String e) {
+    }
+
+    public void setExtra(String[] a) {
+    }
+
+    public boolean transform(Map<String,Set<URI>> pkgSrcs,
+                             Set<URI> visibleSrcs,
+                             Map<URI,Set<String>> visibleClasses,
+                             Map<String,Set<String>> oldPackageDependents,
+                             URI destRoot,
+                             Map<String,Set<URI>>    packageArtifacts,
+                             Map<String,Set<String>> packageDependencies,
+                             Map<String,String>      packagePubapis,
+                             int debugLevel,
+                             boolean incremental,
+                             int numCores,
+                             PrintStream out,
+                             PrintStream err)
+    {
+        boolean rc = true;
+        String dest_filename;
+        File dest;
+
+        for (String pkgName : pkgSrcs.keySet()) {
+            String pkgNameF = Util.toFileSystemPath(pkgName);
+            for (URI u : pkgSrcs.get(pkgName)) {
+                File src = new File(u);
+                File destDir;
+                destDir = new File(destRoot.getPath()+File.separator+pkgNameF);
+                dest_filename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
+                dest = new File(dest_filename);
+
+                if (!destDir.isDirectory()) {
+                    if (!destDir.mkdirs()) {
+                       Log.error("Error: The copier could not create the directory "+
+                                           destDir.getPath());
+                        return false;
+                    }
+                }
+
+                Set<URI> as = packageArtifacts.get(pkgName);
+                if (as == null) {
+                    as = new HashSet<URI>();
+                    packageArtifacts.put(pkgName, as);
+                }
+                as.add(dest.toURI());
+
+                if (dest.exists() && dest.lastModified() > src.lastModified()) {
+                    // A copied file exists, and its timestamp is newer than the source.
+                    continue;
+                }
+
+                Log.info("Copying "+pkgNameF+File.separator+src.getName());
+
+                try (InputStream fin = new FileInputStream(src);
+                     OutputStream fout = new FileOutputStream(dest)) {
+                    byte[] buf = new byte[1024];
+                    int len;
+                    while ((len = fin.read(buf)) > 0){
+                        fout.write(buf, 0, len);
+                    }
+                }
+                catch(IOException e){
+                    Log.error("Could not copy the file "+src.getPath()+" to "+dest.getPath());
+                    rc = false;
+                }
+            }
+        }
+        return rc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.text.SimpleDateFormat;
+import java.net.URI;
+import java.util.*;
+
+/**
+ * The javac state class maintains the previous (prev) and the current (now)
+ * build states and everything else that goes into the javac_state file.
+ *
+ * <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></p>
+ */
+public class JavacState
+{
+    // The arguments to the compile. If not identical, then it cannot
+    // be an incremental build!
+    String theArgs;
+    // The number of cores limits how many threads are used for heavy concurrent work.
+    int numCores;
+
+    // The bin_dir/javac_state
+    private String javacStateFilename;
+    private File javacState;
+
+    // The previous build state is loaded from javac_state
+    private BuildState prev;
+    // The current build state is constructed during the build,
+    // then saved as the new javac_state.
+    private BuildState now;
+
+    // Something has changed in the javac_state. It needs to be saved!
+    private boolean needsSaving;
+    // If this is a new javac_state file, then do not print unnecessary messages.
+    private boolean newJavacState;
+
+    // These are packages where something has changed and the package
+    // needs to be recompiled. Actions that trigger recompilation:
+    // * source belonging to the package has changed
+    // * artifact belonging to the package is lost, or its timestamp has been changed.
+    // * an unknown artifact has appeared, we simply delete it, but we also trigger a recompilation.
+    // * a package that is tainted, taints all packages that depend on it.
+    private Set<String> taintedPackages;
+    // After a compile, the pubapis are compared with the pubapis stored in the javac state file.
+    // Any packages where the pubapi differ are added to this set.
+    // Later we use this set and the dependency information to taint dependent packages.
+    private Set<String> packagesWithChangedPublicApis;
+    // When a module-info.java file is changed, taint the module,
+    // then taint all modules that depend on that that module.
+    // A module dependency can occur directly through a require, or
+    // indirectly through a module that does a public export for the first tainted module.
+    // When all modules are tainted, then taint all packages belonging to these modules.
+    // Then rebuild. It is perhaps possible (and valuable?) to do a more finegrained examination of the
+    // change in module-info.java, but that will have to wait.
+    private Set<String> taintedModules;
+    // The set of all packages that has been recompiled.
+    // Copy over the javac_state for the packages that did not need recompilation,
+    // verbatim from the previous (prev) to the new (now) build state.
+    private Set<String> recompiledPackages;
+
+    // The output directories filled with tasty artifacts.
+    private File binDir, gensrcDir, headerDir;
+
+    // The current status of the file system.
+    private Set<File> binArtifacts;
+    private Set<File> gensrcArtifacts;
+    private Set<File> headerArtifacts;
+
+    // The status of the sources.
+    Set<Source> removedSources = null;
+    Set<Source> addedSources = null;
+    Set<Source> modifiedSources = null;
+
+    // Visible sources for linking. These are the only
+    // ones that -sourcepath is allowed to see.
+    Set<URI> visibleSrcs;
+
+    // Visible classes for linking. These are the only
+    // ones that -classpath is allowed to see.
+    // It maps from a classpath root to the set of visible classes for that root.
+    // If the set is empty, then all classes are visible for that root.
+    // It can also map from a jar file to the set of visible classes for that jar file.
+    Map<URI,Set<String>> visibleClasses;
+
+    // Setup two transforms that always exist.
+    private CopyFile            copyFiles = new CopyFile();
+    private CompileJavaPackages compileJavaPackages = new CompileJavaPackages();
+
+    // Where to send stdout and stderr.
+    private PrintStream out, err;
+
+    JavacState(String[] args, File bd, File gd, File hd, boolean permitUnidentifiedArtifacts, boolean removeJavacState,
+            PrintStream o, PrintStream e) {
+        out = o;
+        err = e;
+        numCores = Main.findNumberOption(args, "-j");
+        theArgs = "";
+        for (String a : removeArgsNotAffectingState(args)) {
+            theArgs = theArgs+a+" ";
+        }
+        binDir = bd;
+        gensrcDir = gd;
+        headerDir = hd;
+        javacStateFilename = binDir.getPath()+File.separator+"javac_state";
+        javacState = new File(javacStateFilename);
+        if (removeJavacState && javacState.exists()) {
+            javacState.delete();
+        }
+        newJavacState = false;
+        if (!javacState.exists()) {
+            newJavacState = true;
+            // If there is no javac_state then delete the contents of all the artifact dirs!
+            // We do not want to risk building a broken incremental build.
+            // BUT since the makefiles still copy things straight into the bin_dir et al,
+            // we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
+            if (!permitUnidentifiedArtifacts) {
+                deleteContents(binDir);
+                deleteContents(gensrcDir);
+                deleteContents(headerDir);
+            }
+            needsSaving = true;
+        }
+        prev = new BuildState();
+        now = new BuildState();
+        taintedPackages = new HashSet<String>();
+        recompiledPackages = new HashSet<String>();
+        packagesWithChangedPublicApis = new HashSet<String>();
+    }
+
+    public BuildState prev() { return prev; }
+    public BuildState now() { return now; }
+
+    /**
+     * Remove args not affecting the state.
+     */
+    static String[] removeArgsNotAffectingState(String[] args) {
+        String[] out = new String[args.length];
+        int j = 0;
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals("-j")) {
+                // Just skip it and skip following value
+                i++;
+            } else if (args[i].startsWith("--server:")) {
+                // Just skip it.
+            } else if (args[i].startsWith("--log=")) {
+                // Just skip it.
+            } else if (args[i].equals("--compare-found-sources")) {
+                // Just skip it and skip verify file name
+                i++;
+            } else {
+                // Copy argument.
+                out[j] = args[i];
+                j++;
+            }
+        }
+        String[] ret = new String[j];
+        System.arraycopy(out, 0, ret, 0, j);
+        return ret;
+    }
+
+    /**
+     * Specify which sources are visible to the compiler through -sourcepath.
+     */
+    public void setVisibleSources(Map<String,Source> vs) {
+        visibleSrcs = new HashSet<URI>();
+        for (String s : vs.keySet()) {
+            Source src = vs.get(s);
+            visibleSrcs.add(src.file().toURI());
+        }
+    }
+
+    /**
+     * Specify which classes are visible to the compiler through -classpath.
+     */
+    public void setVisibleClasses(Map<String,Source> vs) {
+        visibleSrcs = new HashSet<URI>();
+        for (String s : vs.keySet()) {
+            Source src = vs.get(s);
+            visibleSrcs.add(src.file().toURI());
+        }
+    }
+    /**
+     * Returns true if this is an incremental build.
+     */
+    public boolean isIncremental() {
+        return !prev.sources().isEmpty();
+    }
+
+    /**
+     * Find all artifacts that exists on disk.
+     */
+    public void findAllArtifacts() {
+        binArtifacts = findAllFiles(binDir);
+        gensrcArtifacts = findAllFiles(gensrcDir);
+        headerArtifacts = findAllFiles(headerDir);
+    }
+
+    /**
+     * Lookup the artifacts generated for this package in the previous build.
+     */
+    private Map<String,File> fetchPrevArtifacts(String pkg) {
+        Package p = prev.packages().get(pkg);
+        if (p != null) {
+            return p.artifacts();
+        }
+        return new HashMap<String,File>();
+    }
+
+    /**
+     * Delete all prev artifacts in the currently tainted packages.
+     */
+    public void deleteClassArtifactsInTaintedPackages() {
+        for (String pkg : taintedPackages) {
+            Map<String,File> arts = fetchPrevArtifacts(pkg);
+            for (File f : arts.values()) {
+                if (f.exists() && f.getName().endsWith(".class")) {
+                    f.delete();
+                }
+            }
+        }
+    }
+
+    /**
+     * Mark the javac_state file to be in need of saving and as a side effect,
+     * it gets a new timestamp.
+     */
+    private void needsSaving() {
+        needsSaving = true;
+    }
+
+    /**
+     * Save the javac_state file.
+     */
+    public void save() throws IOException {
+        if (!needsSaving) return;
+        try (FileWriter out = new FileWriter(javacStateFilename)) {
+            StringBuilder b = new StringBuilder();
+            long millisNow = System.currentTimeMillis();
+            Date d = new Date(millisNow);
+            SimpleDateFormat df =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
+            b.append("# javac_state ver 0.3 generated "+millisNow+" "+df.format(d)+"\n");
+            b.append("# This format might change at any time. Please do not depend on it.\n");
+            b.append("# M module\n");
+            b.append("# P package\n");
+            b.append("# S C source_tobe_compiled timestamp\n");
+            b.append("# S L link_only_source timestamp\n");
+            b.append("# G C generated_source timestamp\n");
+            b.append("# A artifact timestamp\n");
+            b.append("# D dependency\n");
+            b.append("# I pubapi\n");
+            b.append("# R arguments\n");
+            b.append("R ").append(theArgs).append("\n");
+
+            // Copy over the javac_state for the packages that did not need recompilation.
+            now.copyPackagesExcept(prev, recompiledPackages, new HashSet<String>());
+            // Save the packages, ie package names, dependencies, pubapis and artifacts!
+            // I.e. the lot.
+            Module.saveModules(now.modules(), b);
+
+            String s = b.toString();
+            out.write(s, 0, s.length());
+        }
+    }
+
+    /**
+     * Load a javac_state file.
+     */
+    public static JavacState load(String[] args, File binDir, File gensrcDir, File headerDir,
+            boolean permitUnidentifiedArtifacts, PrintStream out, PrintStream err) {
+        JavacState db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err);
+        Module  lastModule = null;
+        Package lastPackage = null;
+        Source  lastSource = null;
+        boolean noFileFound = false;
+        boolean foundCorrectVerNr = false;
+        boolean newCommandLine = false;
+        boolean syntaxError = false;
+
+        try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
+            for (;;) {
+                String l = in.readLine();
+                if (l==null) break;
+                if (l.length()>=3 && l.charAt(1) == ' ') {
+                    char c = l.charAt(0);
+                    if (c == 'M') {
+                        lastModule = db.prev.loadModule(l);
+                    } else
+                    if (c == 'P') {
+                        if (lastModule == null) { syntaxError = true; break; }
+                        lastPackage = db.prev.loadPackage(lastModule, l);
+                    } else
+                    if (c == 'D') {
+                        if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+                        lastPackage.loadDependency(l);
+                    } else
+                    if (c == 'I') {
+                        if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+                        lastPackage.loadPubapi(l);
+                    } else
+                    if (c == 'A') {
+                        if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+                        lastPackage.loadArtifact(l);
+                    } else
+                    if (c == 'S') {
+                        if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+                        lastSource = db.prev.loadSource(lastPackage, l, false);
+                    } else
+                    if (c == 'G') {
+                        if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+                        lastSource = db.prev.loadSource(lastPackage, l, true);
+                    } else
+                    if (c == 'R') {
+                        String ncmdl = "R "+db.theArgs;
+                        if (!l.equals(ncmdl)) {
+                            newCommandLine = true;
+                        }
+                    } else
+                         if (c == '#') {
+                        if (l.startsWith("# javac_state ver ")) {
+                            int sp = l.indexOf(" ", 18);
+                            if (sp != -1) {
+                                String ver = l.substring(18,sp);
+                                if (!ver.equals("0.3")) {
+                    break;
+                                 }
+                foundCorrectVerNr = true;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (FileNotFoundException e) {
+            // Silently create a new javac_state file.
+            noFileFound = true;
+        } catch (IOException e) {
+            Log.info("Dropping old javac_state because of errors when reading it.");
+            db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+            foundCorrectVerNr = true;
+            newCommandLine = false;
+            syntaxError = false;
+    }
+        if (foundCorrectVerNr == false && !noFileFound) {
+            Log.info("Dropping old javac_state since it is of an old version.");
+            db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+        } else
+        if (newCommandLine == true && !noFileFound) {
+            Log.info("Dropping old javac_state since a new command line is used!");
+            db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+        } else
+        if (syntaxError == true) {
+            Log.info("Dropping old javac_state since it contains syntax errors.");
+            db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+        }
+        db.prev.calculateDependents();
+        return db;
+    }
+
+    /**
+     * Mark a java package as tainted, ie it needs recompilation.
+     */
+    public void taintPackage(String name, String because) {
+        if (!taintedPackages.contains(name)) {
+            if (because != null) Log.debug("Tainting "+Util.justPackageName(name)+" because "+because);
+            // It has not been tainted before.
+            taintedPackages.add(name);
+            needsSaving();
+            Package nowp = now.packages().get(name);
+            if (nowp != null) {
+                for (String d : nowp.dependents()) {
+                    taintPackage(d, because);
+                }
+            }
+        }
+    }
+
+    /**
+     * This packages need recompilation.
+     */
+    public Set<String> taintedPackages() {
+        return taintedPackages;
+    }
+
+    /**
+     * Clean out the tainted package set, used after the first round of compiles,
+     * prior to propagating dependencies.
+     */
+    public void clearTaintedPackages() {
+        taintedPackages = new HashSet<String>();
+    }
+
+    /**
+     * Go through all sources and check which have been removed, added or modified
+     * and taint the corresponding packages.
+     */
+    public void checkSourceStatus(boolean check_gensrc) {
+        removedSources = calculateRemovedSources();
+        for (Source s : removedSources) {
+            if (!s.isGenerated() || check_gensrc) {
+                taintPackage(s.pkg().name(), "source "+s.name()+" was removed");
+            }
+        }
+
+        addedSources = calculateAddedSources();
+        for (Source s : addedSources) {
+            String msg = null;
+            if (isIncremental()) {
+                // When building from scratch, there is no point
+                // printing "was added" for every file since all files are added.
+                // However for an incremental build it makes sense.
+                msg = "source "+s.name()+" was added";
+            }
+            if (!s.isGenerated() || check_gensrc) {
+                taintPackage(s.pkg().name(), msg);
+            }
+        }
+
+        modifiedSources = calculateModifiedSources();
+        for (Source s : modifiedSources) {
+            if (!s.isGenerated() || check_gensrc) {
+                taintPackage(s.pkg().name(), "source "+s.name()+" was modified");
+            }
+        }
+    }
+
+    /**
+     * Acquire the compile_java_packages suffix rule for .java files.
+     */
+    public Map<String,Transformer> getJavaSuffixRule() {
+        Map<String,Transformer> sr = new HashMap<String,Transformer>();
+        sr.put(".java", compileJavaPackages);
+        return sr;
+    }
+
+    /**
+     * Acquire the copying transform.
+     */
+    public Transformer getCopier() {
+        return copyFiles;
+    }
+
+    /**
+     * If artifacts have gone missing, force a recompile of the packages
+     * they belong to.
+     */
+    public void taintPackagesThatMissArtifacts() {
+        for (Package pkg : prev.packages().values()) {
+            for (File f : pkg.artifacts().values()) {
+                if (!f.exists()) {
+                    // Hmm, the artifact on disk does not exist! Someone has removed it....
+                    // Lets rebuild the package.
+                    taintPackage(pkg.name(), ""+f+" is missing.");
+                }
+            }
+        }
+    }
+
+    /**
+     * Propagate recompilation through the dependency chains.
+     * Avoid re-tainting packages that have already been compiled.
+     */
+    public void taintPackagesDependingOnChangedPackages(Set<String> pkgs, Set<String> recentlyCompiled) {
+        for (Package pkg : prev.packages().values()) {
+            for (String dep : pkg.dependencies()) {
+                if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
+                    taintPackage(pkg.name(), " its depending on "+dep);
+                }
+            }
+        }
+    }
+
+    /**
+     * Scan all output dirs for artifacts and remove those files (artifacts?)
+     * that are not recognized as such, in the javac_state file.
+     */
+    public void removeUnidentifiedArtifacts() {
+        Set<File> allKnownArtifacts = new HashSet<File>();
+        for (Package pkg : prev.packages().values()) {
+            for (File f : pkg.artifacts().values()) {
+                allKnownArtifacts.add(f);
+            }
+        }
+        // Do not forget about javac_state....
+        allKnownArtifacts.add(javacState);
+
+        for (File f : binArtifacts) {
+            if (!allKnownArtifacts.contains(f)) {
+                Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+                f.delete();
+            }
+        }
+        for (File f : headerArtifacts) {
+            if (!allKnownArtifacts.contains(f)) {
+                Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+                f.delete();
+            }
+        }
+        for (File f : gensrcArtifacts) {
+            if (!allKnownArtifacts.contains(f)) {
+                Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+                f.delete();
+            }
+        }
+    }
+
+    /**
+     * Remove artifacts that are no longer produced when compiling!
+     */
+    public void removeSuperfluousArtifacts(Set<String> recentlyCompiled) {
+        // Nothing to do, if nothing was recompiled.
+        if (recentlyCompiled.size() == 0) return;
+
+        for (String pkg : now.packages().keySet()) {
+            // If this package has not been recompiled, skip the check.
+            if (!recentlyCompiled.contains(pkg)) continue;
+            Collection<File> arts = now.artifacts().values();
+            for (File f : fetchPrevArtifacts(pkg).values()) {
+                if (!arts.contains(f)) {
+                    Log.debug("Removing "+f.getPath()+" since it is now superfluous!");
+                    if (f.exists()) f.delete();
+                }
+            }
+        }
+    }
+
+    /**
+     * Return those files belonging to prev, but not now.
+     */
+    private Set<Source> calculateRemovedSources() {
+        Set<Source> removed = new HashSet<Source>();
+        for (String src : prev.sources().keySet()) {
+            if (now.sources().get(src) == null) {
+                removed.add(prev.sources().get(src));
+            }
+        }
+        return removed;
+    }
+
+    /**
+     * Return those files belonging to now, but not prev.
+     */
+    private Set<Source> calculateAddedSources() {
+        Set<Source> added = new HashSet<Source>();
+        for (String src : now.sources().keySet()) {
+            if (prev.sources().get(src) == null) {
+                added.add(now.sources().get(src));
+            }
+        }
+        return added;
+    }
+
+    /**
+     * Return those files where the timestamp is newer.
+     * If a source file timestamp suddenly is older than what is known
+     * about it in javac_state, then consider it modified, but print
+     * a warning!
+     */
+    private Set<Source> calculateModifiedSources() {
+        Set<Source> modified = new HashSet<Source>();
+        for (String src : now.sources().keySet()) {
+            Source n = now.sources().get(src);
+            Source t = prev.sources().get(src);
+            if (prev.sources().get(src) != null) {
+                if (t != null) {
+                    if (n.lastModified() > t.lastModified()) {
+                        modified.add(n);
+                    } else if (n.lastModified() < t.lastModified()) {
+                        modified.add(n);
+                        Log.warn("The source file "+n.name()+" timestamp has moved backwards in time.");
+                    }
+                }
+            }
+        }
+        return modified;
+    }
+
+    /**
+     * Recursively delete a directory and all its contents.
+     */
+    private static void deleteContents(File dir) {
+        if (dir != null && dir.exists()) {
+            for (File f : dir.listFiles()) {
+                if (f.isDirectory()) {
+                    deleteContents(f);
+                }
+                f.delete();
+            }
+        }
+    }
+
+    /**
+     * Run the copy translator only.
+     */
+    public void performCopying(File binDir, Map<String,Transformer> suffixRules) {
+        Map<String,Transformer> sr = new HashMap<String,Transformer>();
+        for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
+            if (e.getValue() == copyFiles) {
+                sr.put(e.getKey(), e.getValue());
+            }
+        }
+        perform(binDir, sr);
+    }
+
+    /**
+     * Run all the translators that translate into java source code.
+     * I.e. all translators that are not copy nor compile_java_source.
+     */
+    public void performTranslation(File gensrcDir, Map<String,Transformer> suffixRules) {
+        Map<String,Transformer> sr = new HashMap<String,Transformer>();
+        for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
+            if (e.getValue() != copyFiles &&
+                e.getValue() != compileJavaPackages) {
+                sr.put(e.getKey(), e.getValue());
+            }
+        }
+        perform(gensrcDir, sr);
+    }
+
+    /**
+     * Compile all the java sources. Return true, if it needs to be called again!
+     */
+    public boolean performJavaCompilations(File binDir,
+                                           String serverSettings,
+                                           String[] args,
+                                           Set<String> recentlyCompiled,
+                                           boolean[] rcValue) {
+        Map<String,Transformer> suffixRules = new HashMap<String,Transformer>();
+        suffixRules.put(".java", compileJavaPackages);
+        compileJavaPackages.setExtra(serverSettings);
+        compileJavaPackages.setExtra(args);
+
+        rcValue[0] = perform(binDir, suffixRules);
+        recentlyCompiled.addAll(taintedPackages());
+        clearTaintedPackages();
+        boolean again = !packagesWithChangedPublicApis.isEmpty();
+        taintPackagesDependingOnChangedPackages(packagesWithChangedPublicApis, recentlyCompiled);
+        packagesWithChangedPublicApis = new HashSet<String>();
+        return again && rcValue[0];
+    }
+
+    /**
+     * Store the source into the set of sources belonging to the given transform.
+     */
+    private void addFileToTransform(Map<Transformer,Map<String,Set<URI>>> gs, Transformer t, Source s) {
+        Map<String,Set<URI>> fs = gs.get(t);
+        if (fs == null) {
+            fs = new HashMap<String,Set<URI>>();
+            gs.put(t, fs);
+        }
+        Set<URI> ss = fs.get(s.pkg().name());
+        if (ss == null) {
+            ss = new HashSet<URI>();
+            fs.put(s.pkg().name(), ss);
+        }
+        ss.add(s.file().toURI());
+    }
+
+    /**
+     * For all packages, find all sources belonging to the package, group the sources
+     * based on their transformers and apply the transformers on each source code group.
+     */
+    private boolean perform(File outputDir, Map<String,Transformer> suffixRules)
+    {
+        boolean rc = true;
+        // Group sources based on transforms. A source file can only belong to a single transform.
+        Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<Transformer,Map<String,Set<URI>>>();
+        for (Source src : now.sources().values()) {
+            Transformer t = suffixRules.get(src.suffix());
+               if (t != null) {
+                if (taintedPackages.contains(src.pkg().name()) && !src.isLinkedOnly()) {
+                    addFileToTransform(groupedSources, t, src);
+                }
+            }
+        }
+        // Go through the transforms and transform them.
+        for (Map.Entry<Transformer,Map<String,Set<URI>>> e : groupedSources.entrySet()) {
+            Transformer t = e.getKey();
+            Map<String,Set<URI>> srcs = e.getValue();
+            // These maps need to be synchronized since multiple threads will be writing results into them.
+            Map<String,Set<URI>> packageArtifacts = Collections.synchronizedMap(new HashMap<String,Set<URI>>());
+            Map<String,Set<String>> packageDependencies = Collections.synchronizedMap(new HashMap<String,Set<String>>());
+            Map<String,String> packagePublicApis = Collections.synchronizedMap(new HashMap<String,String>());
+
+            boolean  r = t.transform(srcs,
+                                     visibleSrcs,
+                                     visibleClasses,
+                                     prev.dependents(),
+                                     outputDir.toURI(),
+                                     packageArtifacts,
+                                     packageDependencies,
+                                     packagePublicApis,
+                                     0,
+                                     isIncremental(),
+                                     numCores,
+                                     out,
+                                     err);
+            if (!r) rc = false;
+
+            for (String p : srcs.keySet()) {
+                recompiledPackages.add(p);
+            }
+            // The transform is done! Extract all the artifacts and store the info into the Package objects.
+            for (Map.Entry<String,Set<URI>> a : packageArtifacts.entrySet()) {
+                Module mnow = now.findModuleFromPackageName(a.getKey());
+                mnow.addArtifacts(a.getKey(), a.getValue());
+            }
+            // Extract all the dependencies and store the info into the Package objects.
+            for (Map.Entry<String,Set<String>> a : packageDependencies.entrySet()) {
+                Set<String> deps = a.getValue();
+                Module mnow = now.findModuleFromPackageName(a.getKey());
+                mnow.setDependencies(a.getKey(), deps);
+            }
+            // Extract all the pubapis and store the info into the Package objects.
+            for (Map.Entry<String,String> a : packagePublicApis.entrySet()) {
+                Module mprev = prev.findModuleFromPackageName(a.getKey());
+                List<String> pubapi = Package.pubapiToList(a.getValue());
+                Module mnow = now.findModuleFromPackageName(a.getKey());
+                mnow.setPubapi(a.getKey(), pubapi);
+                if (mprev.hasPubapiChanged(a.getKey(), pubapi)) {
+                    // Aha! The pubapi of this package has changed!
+                    // It can also be a new compile from scratch.
+                    if (mprev.lookupPackage(a.getKey()).existsInJavacState()) {
+                        // This is an incremental compile! The pubapi
+                        // did change. Trigger recompilation of dependents.
+                        packagesWithChangedPublicApis.add(a.getKey());
+                        Log.info("The pubapi of "+Util.justPackageName(a.getKey())+" has changed!");
+                    }
+                }
+            }
+        }
+        return rc;
+    }
+
+    /**
+     * Utility method to recursively find all files below a directory.
+     */
+    private static Set<File> findAllFiles(File dir) {
+        Set<File> foundFiles = new HashSet<File>();
+        if (dir == null) {
+            return foundFiles;
+        }
+        recurse(dir, foundFiles);
+        return foundFiles;
+    }
+
+    private static void recurse(File dir, Set<File> foundFiles) {
+        for (File f : dir.listFiles()) {
+            if (f.isFile()) {
+                foundFiles.add(f);
+            } else if (f.isDirectory()) {
+                recurse(f, foundFiles);
+            }
+        }
+    }
+
+    /**
+     * Compare the calculate source list, with an explicit list, usually supplied from the makefile.
+     * Used to detect bugs where the makefile and sjavac have different opinions on which files
+     * should be compiled.
+     */
+    public void compareWithMakefileList(File makefileSourceList)
+            throws ProblemException
+    {
+        // If we are building on win32 using for example cygwin the paths in the makefile source list
+        // might be /cygdrive/c/.... which does not match c:\....
+        // We need to adjust our calculated sources to be identical, if necessary.
+        boolean mightNeedRewriting = File.pathSeparatorChar == ';';
+
+        if (makefileSourceList == null) return;
+
+        Set<String> calculatedSources = new HashSet<String>();
+        Set<String> listedSources = new HashSet<String>();
+
+        // Create a set of filenames with full paths.
+        for (Source s : now.sources().values()) {
+            calculatedSources.add(s.file().getPath());
+        }
+        // Read in the file and create another set of filenames with full paths.
+        try {
+            BufferedReader in = new BufferedReader(new FileReader(makefileSourceList));
+            for (;;) {
+                String l = in.readLine();
+                if (l==null) break;
+                l = l.trim();
+                if (mightNeedRewriting) {
+                    if (l.indexOf(":") == 1 && l.indexOf("\\") == 2) {
+                        // Everything a-ok, the format is already C:\foo\bar
+                    } else if (l.indexOf(":") == 1 && l.indexOf("/") == 2) {
+                        // The format is C:/foo/bar, rewrite into the above format.
+                        l = l.replaceAll("/","\\\\");
+                    } else if (l.charAt(0) == '/' && l.indexOf("/",1) != -1) {
+                        // The format might be: /cygdrive/c/foo/bar, rewrite into the above format.
+                        // Do not hardcode the name cygdrive here.
+                        int slash = l.indexOf("/",1);
+                        l = l.replaceAll("/","\\\\");
+                        l = ""+l.charAt(slash+1)+":"+l.substring(slash+2);
+                    }
+                    if (Character.isLowerCase(l.charAt(0))) {
+                        l = Character.toUpperCase(l.charAt(0))+l.substring(1);
+                    }
+                }
+                listedSources.add(l);
+            }
+        } catch (FileNotFoundException e) {
+            throw new ProblemException("Could not open "+makefileSourceList.getPath()+" since it does not exist!");
+        } catch (IOException e) {
+            throw new ProblemException("Could not read "+makefileSourceList.getPath());
+        }
+
+        for (String s : listedSources) {
+            if (!calculatedSources.contains(s)) {
+                 throw new ProblemException("The makefile listed source "+s+" was not calculated by the smart javac wrapper!");
+            }
+        }
+
+        for (String s : calculatedSources) {
+            if (!listedSources.contains(s)) {
+                throw new ProblemException("The smart javac wrapper calculated source "+s+" was not listed by the makefiles!");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.sjavac;
+
+import java.io.PrintStream;
+
+/**
+ * Utility class only for sjavac logging.
+ * The log level can be set using for example --log=DEBUG on the sjavac command line.
+ *
+ * <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></p>
+ */
+public class Log {
+    private static PrintStream out, err;
+
+    public final static int WARN = 1;
+    public final static int INFO = 2;
+    public final static int DEBUG = 3;
+    public final static int TRACE = 4;
+    private static int level = WARN;
+
+    static public void trace(String msg) {
+        if (level >= TRACE) {
+            out.println(msg);
+        }
+    }
+
+    static public void debug(String msg) {
+        if (level >= DEBUG) {
+            out.println(msg);
+        }
+    }
+
+    static public void info(String msg) {
+        if (level >= INFO) {
+            out.println(msg);
+        }
+    }
+
+    static public void warn(String msg) {
+        err.println(msg);
+    }
+
+    static public void error(String msg) {
+        err.println(msg);
+    }
+
+    static public void setLogLevel(String l, PrintStream o, PrintStream e)
+        throws ProblemException {
+        out = o;
+        err = e;
+        if (l.equals("warn")) level = WARN;
+        else if (l.equals("info")) level = INFO;
+        else if (l.equals("debug")) level = DEBUG;
+        else if (l.equals("trace")) level = TRACE;
+        else throw new ProblemException("No such log level \""+l+"\"");
+    }
+
+    static public boolean isTracing() {
+        return level >= TRACE;
+    }
+
+    static public boolean isDebugging() {
+        return level >= DEBUG;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import com.sun.tools.sjavac.server.JavacServer;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.*;
+
+/**
+ * The main class of the smart javac wrapper tool.
+ *
+ * <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></p>
+ */
+public class Main {
+
+    /*  This is a smart javac wrapper primarily used when building the OpenJDK,
+        though other projects are welcome to use it too. But please be aware
+        that it is not an official api and will change in the future.
+        (We really mean it!)
+
+        Goals:
+
+        ** Create a state file, containing information about the build, so
+           that incremental builds only rebuild what is necessary. Also the
+           state file can be used by make/ant to detect when to trigger
+           a call to the smart javac wrapper.
+
+           This file is called bin/javac_state (assuming that you specified "-d bin")
+           Thus the simplest makefile is:
+
+           SJAVAC=java -cp .../tools.jar com.sun.tools.sjavac.Main
+           SRCS=$(shell find src -name "*.java")
+           bin/javac_state : $(SRCS)
+                  $(SJAVAC) src -d bin
+
+           This makefile will run very fast and detect properly when Java code needs to
+           be recompiled. The smart javac wrapper will then use the information in java_state
+           to do an efficient incremental compile.
+
+           Previously it was near enough impossible to write an efficient makefile for Java
+           with support for incremental builds and dependency tracking.
+
+        ** Separate java sources to be compiled from java
+           sources used >only< for linking. The options:
+
+           "dir" points to root dir with sources to be compiled
+           "-sourcepath dir" points to root dir with sources used only for linking
+           "-classpath dir" points to dir with classes used only for linking (as before)
+
+        ** Use all cores for compilation by default.
+           "-j 4" limit the number of cores to 4.
+           For the moment, the sjavac server additionally limits the number of cores to three.
+           This will improve in the future when more sharing is performed between concurrent JavaCompilers.
+
+        ** Basic translation support from other sources to java, and then compilation of the generated java.
+           This functionality might be moved into annotation processors instead.
+           Again this is driven by the OpenJDK sources where properties and a few other types of files
+           are converted into Java sources regularily. The javac_state embraces copy and tr, and perform
+           incremental recompiles and copying for these as well. META-INF will be a special copy rule
+           that will copy any files found below any META-INF dir in src to the bin/META-INF dir.
+           "-copy .gif"
+           "-copy META-INF"
+           "-tr .prop=com.sun.tools.javac.smart.CompileProperties
+           "-tr .propp=com.sun.tools.javac.smart.CompileProperties,java.util.ListResourceBundle
+           "-tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
+
+        ** Control which classes in the src,sourcepath and classpath that javac is allowed to see.
+           Again, this is necessary to deal with the source code structure of the OpenJDK which is
+           intricate (read messy).
+
+           "-i tools.*" to include the tools package and all its subpackages in the build.
+           "-x tools.net.aviancarrier.*" to exclude the aviancarrier package and all its sources and subpackages.
+           "-x tools.net.drums" to exclude the drums package only, keep its subpackages.
+           "-xf tools/net/Bar.java" // Do not compile this file...
+           "-xf *Bor.java" // Do not compile Bor.java wherever it is found, BUT do compile ABor.java!
+           "-if tools/net/Bor.java" // Only compile this file...odd, but sometimes used.
+
+        ** The smart javac wrapper is driven by the modification time on the source files and compared
+           to the modification times written into the javac_state file.
+
+           It does not compare the modification time of the source with the modification time of the artifact.
+           However it will detect if the modification time of an artifact has changed compared to the java_state,
+           and this will trigger a delete of the artifact and a subsequent recompile of the source.
+
+           The smart javac wrapper is not a generic makefile/ant system. Its purpose is to compile java source
+           as the final step before the output dir is finalized and immediately jared, or jmodded. The output
+           dir should be considered opaque. Do not write into the outputdir yourself!
+           Any artifacts found in the outputdir that javac_state does not know of, will be deleted!
+           This can however be prevented, using the switch --permit-unidentified-artifacts
+           This switch is necessary when build the OpenJDK because its makefiles still write directly to
+           the output classes dirs.
+
+           Any makefile/ant rules that want to put contents into the outputdir should put the content
+           in one of several source roots. Static content that is under version control, can be put in the same source
+           code tree as the Java sources. Dynamic content that is generated by make/ant on the fly, should
+           be put in a separate gensrc_stuff root. The smart javac wrapper call will then take the arguments:
+           "gensrc_stuff src -d bin"
+
+        The command line:
+        java -cp tools.jar com.sun.tools.sjavac.Main \
+             -i "com.bar.*" -x "com.bar.foo.*" \
+             first_root \
+             -i "com.bar.foo.*" \
+             second_root \
+             -x "org.net.*" \
+             -sourcepath link_root_sources \
+             -classpath link_root_classes \
+             -d bin
+
+        Will compile all sources for package com.bar and its subpackages, found below first_root,
+        except the package com.bar.foo (and its subpackages), for which the sources are picked
+        from second_root instead. It will link against classes in link_root_classes and against
+        sources in link_root_sources, but will not see (try to link against) sources matching org.net.*
+        but will link against org.net* classes (if they exist) in link_root_classes.
+
+        (If you want a set of complex filter rules to be applied to several source directories, without
+         having to repeat the the filter rules for each root. You can use the explicit -src option. For example:
+         sjavac -x "com.foo.*" -src root1:root2:root3  )
+
+        The resulting classes are written into bin.
+    */
+
+    // This is the final destination for classes and copied files.
+    private File bin_dir;
+    // This is where the annotation process will put generated sources.
+    private File gensrc_dir;
+    // This is where javac -h puts the generated c-header files.
+    private File header_dir;
+
+    // This file contains the list of sources genereated by the makefile.
+    // We double check that our calculated list of sources matches this list,
+    // if not, then we terminate with an error!
+    private File makefile_source_list;
+    // The challenging task to manage an incremental build is done by javac_state.
+    private JavacState javac_state;
+
+    // The suffix rules tells you for example, that .java files should be compiled,
+    // and .html files should be copied and .properties files be translated.
+    Map<String,Transformer> suffix_rules;
+
+    public static void main(String... args)  {
+        if (args.length > 0 && args[0].startsWith("--startserver:")) {
+            if (args.length>1) {
+                Log.error("When spawning a background server, only a single --startserver argument is allowed.");
+                return;
+            }
+            // Spawn a background server.
+            int rc = JavacServer.startServer(args[0], System.err);
+            System.exit(rc);
+        }
+        Main main = new Main();
+        int rc = main.go(args, System.out, System.err);
+        // Remove the portfile, but only if this background=false was used.
+        JavacServer.cleanup(args);
+        System.exit(rc);
+    }
+
+    private void printHelp() {
+        System.out.println("Usage: sjavac <options>\n"+
+                           "where required options are:\n"+
+                           "dir                        Compile all sources in dir recursively\n"+
+                           "-d dir                     Store generated classes here and the javac_state file\n"+
+                           "--server:portfile=/tmp/abc Use a background sjavac server\n\n"+
+                           "All other arguments as javac, except -implicit:none which is forced by default.\n"+
+                           "No java source files can be supplied on the command line, nor can an @file be supplied.\n\n"+
+                           "Warning!\n"+
+                           "This tool might disappear at any time, and its command line options might change at any time!");
+    }
+
+    public int go(String[] args, PrintStream out, PrintStream err) {
+        try {
+            if (args.length == 0 || findJavaSourceFiles(args) || findAtFile(args) || null==Util.findServerSettings(args)) {
+                printHelp();
+                return 0;
+            }
+
+            Log.setLogLevel(findLogLevel(args), out, err);
+            String server_settings = Util.findServerSettings(args);
+            args = verifyImplicitOption(args);
+            // Find the source root directories, and add the -src option before these, if not there already.
+            args = addSrcBeforeDirectories(args);
+            // Check that there is at least one -src supplied.
+            checkSrcOption(args);
+            // Check that there is one -d supplied.
+            bin_dir = findDirectoryOption(args,"-d","output", true, false, true);
+            gensrc_dir = findDirectoryOption(args,"-s","gensrc", false, false, true);
+            header_dir = findDirectoryOption(args,"-h","headers", false, false, true);
+            makefile_source_list = findFileOption(args,"--compare-found-sources","makefile source list", false);
+
+            // Load the prev build state database.
+            javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir,
+                    findBooleanOption(args, "--permit-unidentified-artifacts"), out, err);
+
+            // Setup the suffix rules from the command line.
+            suffix_rules = javac_state.getJavaSuffixRule();
+            findTranslateOptions(args, suffix_rules);
+            if (suffix_rules.keySet().size() > 1 && gensrc_dir == null) {
+                Log.error("You have translators but no gensrc dir (-s) specified!");
+                return -1;
+            }
+            findCopyOptions(args, suffix_rules);
+
+            // All found modules are put here.
+            Map<String,Module> modules = new HashMap<String,Module>();
+            // We start out in the legacy empty no-name module.
+            // As soon as we stumble on a module-info.java file we change to that module.
+            Module current_module = new Module("", "");
+            modules.put("", current_module);
+
+            // Find all sources, use the suffix rules to know which files are sources.
+            Map<String,Source> sources = new HashMap<String,Source>();
+            // Find the files, this will automatically populate the found modules
+            // with found packages where the sources are found!
+            findFiles(args, "-src", suffix_rules.keySet(), sources, modules, current_module, false);
+
+            if (sources.isEmpty()) {
+                Log.error("Found nothing to compile!");
+                return -1;
+            }
+
+            // Find all source files allowable for linking.
+            // We might find more modules here as well.
+            Map<String,Source> sources_to_link_to = new HashMap<String,Source>();
+            // Always reuse -src for linking as well! This means that we might
+            // get two -sourcepath on the commandline after the rewrite, which is
+            // fine. We can have as many as we like. You need to have separate -src/-sourcepath/-classpath
+            // if you need different filtering rules for different roots. If you have the same filtering
+            // rules for all sourcepath roots, you can concatenate them using :(;) as before.
+              rewriteOptions(args, "-src", "-sourcepath");
+            findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true);
+
+            // Find all class files allowable for linking.
+            // And pickup knowledge of all modules found here.
+            // This cannot currently filter classes inside jar files.
+            Map<String,Source> classes_to_link_to = new HashMap<String,Source>();
+//          findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true);
+
+            // Find all module sources allowable for linking.
+            Map<String,Source> modules_to_link_to = new HashMap<String,Source>();
+ //         findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true);
+
+            // Add the set of sources to the build database.
+            javac_state.now().collectPackagesSourcesAndArtifacts(modules);
+            javac_state.now().checkInternalState("checking sources", false, sources);
+            javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
+            javac_state.setVisibleSources(sources_to_link_to);
+
+            // If there is any change in the source files, taint packages
+            // and mark the database in need of saving.
+            javac_state.checkSourceStatus(false);
+
+            // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
+            // in javac_state, simply because loading of the JavacState will clean out all artifacts
+            // that do not match the javac_state database.
+            javac_state.findAllArtifacts();
+
+            // Remove unidentified artifacts from the bin, gensrc and header dirs.
+            // (Unless we allow them to be there.)
+            // I.e. artifacts that are not known according to the build database (javac_state).
+            // For examples, files that have been manually copied into these dirs.
+            // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
+            // in javac_state) have already been removed when the javac_state was loaded.
+            if (!findBooleanOption(args, "--permit-unidentified-artifacts")) {
+                javac_state.removeUnidentifiedArtifacts();
+            }
+            // Go through all sources and taint all packages that miss artifacts.
+            javac_state.taintPackagesThatMissArtifacts();
+
+            // Now clean out all known artifacts belonging to tainted packages.
+            javac_state.deleteClassArtifactsInTaintedPackages();
+            // Copy files, for example property files, images files, xml files etc etc.
+            javac_state.performCopying(bin_dir, suffix_rules);
+            // Translate files, for example compile properties or compile idls.
+            javac_state.performTranslation(gensrc_dir, suffix_rules);
+            // Add any potentially generated java sources to the tobe compiled list.
+            // (Generated sources must always have a package.)
+            Map<String,Source> generated_sources = new HashMap<String,Source>();
+            Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null,
+                   generated_sources, modules, current_module, false, true, false);
+            javac_state.now().collectPackagesSourcesAndArtifacts(modules);
+            // Recheck the the source files and their timestamps again.
+            javac_state.checkSourceStatus(true);
+
+            // Now do a safety check that the list of source files is identical
+            // to the list Make believes we are compiling. If we do not get this
+            // right, then incremental builds will fail with subtility.
+            // If any difference is detected, then we will fail hard here.
+            // This is an important safety net.
+            javac_state.compareWithMakefileList(makefile_source_list);
+
+            // Do the compilations, repeatedly until no tainted packages exist.
+            boolean again;
+            // Collect the name of all compiled packages.
+            Set<String> recently_compiled = new HashSet<String>();
+            boolean[] rc = new boolean[1];
+            do {
+                // Clean out artifacts in tainted packages.
+                javac_state.deleteClassArtifactsInTaintedPackages();
+                again = javac_state.performJavaCompilations(bin_dir, server_settings, args, recently_compiled, rc);
+                if (!rc[0]) break;
+            } while (again);
+            // Only update the state if the compile went well.
+            if (rc[0]) {
+                javac_state.save();
+                // Collect all the artifacts.
+                javac_state.now().collectArtifacts(modules);
+                // Remove artifacts that were generated during the last compile, but not this one.
+                javac_state.removeSuperfluousArtifacts(recently_compiled);
+            }
+            return rc[0] ? 0 : -1;
+        } catch (ProblemException e) {
+            Log.error(e.getMessage());
+            return -1;
+        } catch (Exception e) {
+            e.printStackTrace(err);
+            return -1;
+        }
+    }
+
+    /**
+     * Are java source files passed on the command line?
+     */
+    private boolean findJavaSourceFiles(String[] args) {
+        String prev = "";
+        for (String s : args) {
+            if (s.endsWith(".java") && !prev.equals("-xf") && !prev.equals("-if")) {
+                return true;
+            }
+            prev = s;
+        }
+        return false;
+    }
+
+    /**
+     * Is an at file passed on the command line?
+     */
+    private boolean findAtFile(String[] args) {
+        for (String s : args) {
+            if (s.startsWith("@")) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Find the log level setting.
+     */
+    private String findLogLevel(String[] args) {
+        for (String s : args) {
+            if (s.startsWith("--log=") && s.length()>6) {
+                return s.substring(6);
+            }
+            if (s.equals("-verbose")) {
+                return "info";
+            }
+        }
+        return "info";
+    }
+
+    /**
+     * Remove smart javac wrapper arguments, before feeding
+     * the args to the plain javac.
+     */
+    static String[] removeWrapperArgs(String[] args) {
+        String[] out = new String[args.length];
+        // The first source path index is remembered
+        // here. So that all following can be concatenated to it.
+        int source_path = -1;
+        // The same for class path.
+        int class_path = -1;
+        // And module path.
+        int module_path = -1;
+        int j = 0;
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals("-src") ||
+                args[i].equals("-x") ||
+                args[i].equals("-i") ||
+                args[i].equals("-xf") ||
+                args[i].equals("-if") ||
+                args[i].equals("-copy") ||
+                args[i].equals("-tr") ||
+                args[i].equals("-j")) {
+                // Just skip it and skip following value
+                i++;
+            } else if (args[i].startsWith("--server:")) {
+                // Just skip it.
+            } else if (args[i].startsWith("--log=")) {
+                // Just skip it.
+            } else if (args[i].equals("--permit-unidentified-artifacts")) {
+                // Just skip it.
+            } else if (args[i].equals("--permit-sources-without-package")) {
+                // Just skip it.
+            } else if (args[i].equals("--compare-found-sources")) {
+                // Just skip it and skip verify file name
+                i++;
+            } else if (args[i].equals("-sourcepath")) {
+                if (source_path == -1) {
+                    source_path = j;
+                    out[j] = args[i];
+                    out[j+1] = args[i+1];
+                    j+=2;
+                    i++;
+                } else {
+                    // Skip this and its argument, but
+                    // append argument to found sourcepath.
+                    out[source_path+1] = out[source_path+1]+File.pathSeparatorChar+args[i+1];
+                    i++;
+                }
+            } else if (args[i].equals("-classpath")) {
+                if (class_path == -1) {
+                    class_path = j;
+                    out[j] = args[i];
+                    out[j+1] = args[i+1];
+                    j+=2;
+                    i++;
+                } else {
+                    // Skip this and its argument, but
+                    // append argument to found sourcepath.
+                    out[class_path+1] = out[class_path+1]+File.pathSeparatorChar+args[i+1];
+                    i++;
+                }
+            } else if (args[i].equals("-modulepath")) {
+                if (module_path == -1) {
+                    module_path = j;
+                    out[j] = args[i];
+                    out[j+1] = args[i+1];
+                    j+=2;
+                    i++;
+                } else {
+                    // Skip this and its argument, but
+                    // append argument to found sourcepath.
+                    out[module_path+1] = out[module_path+1]+File.pathSeparatorChar+args[i+1];
+                    i++;
+                }
+             } else {
+                // Copy argument.
+                out[j] = args[i];
+                j++;
+            }
+        }
+        String[] ret = new String[j];
+        System.arraycopy(out, 0, ret, 0, j);
+        return ret;
+    }
+
+    /**
+     * Make sure directory exist, create it if not.
+     */
+    private static boolean makeSureExists(File dir) {
+        // Make sure the dest directories exist.
+        if (!dir.exists()) {
+            if (!dir.mkdirs()) {
+                Log.error("Could not create the directory "+dir.getPath());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Verify that a package pattern is valid.
+     */
+    private static void checkPattern(String s) throws ProblemException {
+        // Package names like foo.bar.gamma are allowed, and
+        // package names suffixed with .* like foo.bar.* are
+        // also allowed.
+        Pattern p = Pattern.compile("[a-zA-Z_]{1}[a-zA-Z0-9_]*(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)*(\\.\\*)?+");
+        Matcher m = p.matcher(s);
+        if (!m.matches()) {
+            throw new ProblemException("The string \""+s+"\" is not a proper package name pattern.");
+        }
+    }
+
+    /**
+     * Verify that a translate pattern is valid.
+     */
+    private static void checkTranslatePattern(String s) throws ProblemException {
+        // .prop=com.sun.tools.javac.smart.CompileProperties
+        // .idl=com.sun.corba.CompileIdl
+        // .g3=antlr.CompileGrammar,debug=true
+        Pattern p = Pattern.compile(
+            "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*=[a-z_]{1}[a-z0-9_]*(\\.[a-z_]{1}[a-z0-9_]*)*"+
+            "(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)(,.*)?");
+        Matcher m = p.matcher(s);
+        if (!m.matches()) {
+            throw new ProblemException("The string \""+s+"\" is not a proper translate pattern.");
+        }
+    }
+
+    /**
+     * Verify that a copy pattern is valid.
+     */
+    private static void checkCopyPattern(String s) throws ProblemException {
+        // .gif
+        // .html
+        Pattern p = Pattern.compile(
+            "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*");
+        Matcher m = p.matcher(s);
+        if (!m.matches()) {
+            throw new ProblemException("The string \""+s+"\" is not a proper suffix.");
+        }
+    }
+
+    /**
+     * Verify that a source file name is valid.
+     */
+    private static void checkFilePattern(String s) throws ProblemException {
+        // File names like foo/bar/gamma/Bar.java are allowed,
+        // as well as /bar/jndi.properties as well as,
+        // */bar/Foo.java
+        Pattern p = null;
+        if (File.separatorChar == '\\') {
+            p = Pattern.compile("\\*?(.+\\\\)*.+");
+        }
+        else if (File.separatorChar == '/') {
+            p = Pattern.compile("\\*?(.+/)*.+");
+        } else {
+            throw new ProblemException("This platform uses the unsupported "+File.separatorChar+
+                                      " as file separator character. Please add support for it!");
+        }
+        Matcher m = p.matcher(s);
+        if (!m.matches()) {
+            throw new ProblemException("The string \""+s+"\" is not a proper file name.");
+        }
+    }
+
+    /**
+     * Scan the arguments to find an option is used.
+     */
+    private static boolean hasOption(String[] args, String option) {
+        for (String a : args) {
+            if (a.equals(option)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if -implicit is supplied, if so check that it is none.
+     * If -implicit is not supplied, supply -implicit:none
+     * Only implicit:none is allowed because otherwise the multicore compilations
+     * and dependency tracking will be tangled up.
+     */
+    private static String[] verifyImplicitOption(String[] args)
+        throws ProblemException {
+
+        boolean foundImplicit = false;
+        for (String a : args) {
+            if (a.startsWith("-implicit:")) {
+                foundImplicit = true;
+                if (!a.equals("-implicit:none")) {
+                    throw new ProblemException("The only allowed setting for sjavac is -implicit:none, it is also the default.");
+                }
+            }
+        }
+        if (foundImplicit) {
+            return args;
+        }
+        // -implicit:none not found lets add it.
+        String[] newargs = new String[args.length+1];
+        System.arraycopy(args,0, newargs, 0, args.length);
+        newargs[args.length] = "-implicit:none";
+        return newargs;
+    }
+
+    /**
+     * Rewrite a single option into something else.
+     */
+    private static void rewriteOptions(String[] args, String option, String new_option) {
+        for (int i=0; i<args.length; ++i) {
+            if (args[i].equals(option)) {
+                args[i] = new_option;
+            }
+        }
+    }
+
+    /**
+     * Scan the arguments to find an option that specifies a directory.
+     * Create the directory if necessary.
+     */
+    private static File findDirectoryOption(String[] args, String option, String name, boolean needed, boolean allow_dups, boolean create)
+        throws ProblemException, ProblemException {
+        File dir = null;
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals(option)) {
+                if (dir != null) {
+                    throw new ProblemException("You have already specified the "+name+" dir!");
+                }
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a directory following "+option+".");
+                }
+                if (args[i+1].indexOf(File.pathSeparatorChar) != -1) {
+                    throw new ProblemException("You must only specify a single directory for "+option+".");
+                }
+                dir = new File(args[i+1]);
+                if (!dir.exists()) {
+                    if (!create) {
+                         throw new ProblemException("This directory does not exist: "+dir.getPath());
+                    } else
+                    if (!makeSureExists(dir)) {
+                        throw new ProblemException("Cannot create directory "+dir.getPath());
+                    }
+                }
+                if (!dir.isDirectory()) {
+                    throw new ProblemException("\""+args[i+1]+"\" is not a directory.");
+                }
+            }
+        }
+        if (dir == null && needed) {
+            throw new ProblemException("You have to specify "+option);
+        }
+        try {
+            if (dir != null)
+                return dir.getCanonicalFile();
+        } catch (IOException e) {
+            throw new ProblemException(""+e);
+        }
+        return null;
+    }
+
+    /**
+     * Option is followed by path.
+     */
+    private static boolean shouldBeFollowedByPath(String o) {
+        return o.equals("-s") ||
+               o.equals("-h") ||
+               o.equals("-d") ||
+               o.equals("-sourcepath") ||
+               o.equals("-classpath") ||
+               o.equals("-bootclasspath") ||
+               o.equals("-src");
+    }
+
+    /**
+     * Add -src before source root directories if not already there.
+     */
+    private static String[] addSrcBeforeDirectories(String[] args) {
+        List<String> newargs = new ArrayList<String>();
+        for (int i = 0; i<args.length; ++i) {
+            File dir = new File(args[i]);
+            if (dir.exists() && dir.isDirectory()) {
+                if (i == 0 || !shouldBeFollowedByPath(args[i-1])) {
+                    newargs.add("-src");
+                }
+            }
+            newargs.add(args[i]);
+        }
+        return newargs.toArray(new String[0]);
+    }
+
+    /**
+     * Check the -src options.
+     */
+    private static void checkSrcOption(String[] args)
+        throws ProblemException {
+        Set<File> dirs = new HashSet<File>();
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals("-src")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a directory following -src.");
+                }
+                StringTokenizer st = new StringTokenizer(args[i+1], File.pathSeparator);
+                while (st.hasMoreElements()) {
+                    File dir = new File(st.nextToken());
+                    if (!dir.exists()) {
+                        throw new ProblemException("This directory does not exist: "+dir.getPath());
+                    }
+                    if (!dir.isDirectory()) {
+                        throw new ProblemException("\""+dir.getPath()+"\" is not a directory.");
+                    }
+                    if (dirs.contains(dir)) {
+                        throw new ProblemException("The src directory \""+dir.getPath()+"\" is specified more than once!");
+                    }
+                    dirs.add(dir);
+                }
+            }
+        }
+        if (dirs.isEmpty()) {
+            throw new ProblemException("You have to specify -src.");
+        }
+    }
+
+    /**
+     * Scan the arguments to find an option that specifies a file.
+     */
+    private static File findFileOption(String[] args, String option, String name, boolean needed)
+        throws ProblemException, ProblemException {
+        File file = null;
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals(option)) {
+                if (file != null) {
+                    throw new ProblemException("You have already specified the "+name+" file!");
+                }
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a file following "+option+".");
+                }
+                file = new File(args[i+1]);
+                if (file.isDirectory()) {
+                    throw new ProblemException("\""+args[i+1]+"\" is not a file.");
+                }
+                if (!file.exists() && needed) {
+                    throw new ProblemException("The file \""+args[i+1]+"\" does not exist.");
+                }
+
+            }
+        }
+        if (file == null && needed) {
+            throw new ProblemException("You have to specify "+option);
+        }
+        return file;
+    }
+
+    /**
+     * Look for a specific switch, return true if found.
+     */
+    public static boolean findBooleanOption(String[] args, String option) {
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals(option)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Scan the arguments to find an option that specifies a number.
+     */
+    public static int findNumberOption(String[] args, String option) {
+        int rc = 0;
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals(option)) {
+                if (args.length > i+1) {
+                    rc = Integer.parseInt(args[i+1]);
+                }
+            }
+        }
+        return rc;
+    }
+
+    /**
+     * Scan the arguments to find the option (-tr) that setup translation rules to java source
+     * from different sources. For example: .properties are translated using CompileProperties
+     * The found translators are stored as suffix rules.
+     */
+    private static void findTranslateOptions(String[] args, Map<String,Transformer> suffix_rules)
+        throws ProblemException, ProblemException {
+
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals("-tr")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a translate rule following -tr.");
+                }
+                String s = args[i+1];
+                checkTranslatePattern(s);
+                int ep = s.indexOf("=");
+                String suffix = s.substring(0,ep);
+                String classname = s.substring(ep+1);
+                if (suffix_rules.get(suffix) != null) {
+                    throw new ProblemException("You have already specified a "+
+                                              "rule for the suffix "+suffix);
+                }
+                if (s.equals(".class")) {
+                    throw new ProblemException("You cannot have a translator for .class files!");
+                }
+                if (s.equals(".java")) {
+                    throw new ProblemException("You cannot have a translator for .java files!");
+                }
+                String extra = null;
+                int exp = classname.indexOf(",");
+                if (exp != -1) {
+                    extra = classname.substring(exp+1);
+                    classname = classname.substring(0,exp);
+                }
+                try {
+                    Class<?> cl = Class.forName(classname);
+                    Transformer t = (Transformer)cl.newInstance();
+                    t.setExtra(extra);
+                    suffix_rules.put(suffix, t);
+                }
+                catch (Exception e) {
+                    throw new ProblemException("Cannot use "+classname+" as a translator!");
+                }
+            }
+        }
+    }
+
+    /**
+     * Scan the arguments to find the option (-copy) that setup copying rules into the bin dir.
+     * For example: -copy .html
+     * The found copiers are stored as suffix rules as well. No translation is done, just copying.
+     */
+    private void findCopyOptions(String[] args, Map<String,Transformer> suffix_rules)
+        throws ProblemException, ProblemException {
+
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals("-copy")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a translate rule following -tr.");
+                }
+                String s = args[i+1];
+                checkCopyPattern(s);
+                if (suffix_rules.get(s) != null) {
+                    throw new ProblemException("You have already specified a "+
+                                              "rule for the suffix "+s);
+                }
+                if (s.equals(".class")) {
+                    throw new ProblemException("You cannot have a copy rule for .class files!");
+                }
+                if (s.equals(".java")) {
+                    throw new ProblemException("You cannot have a copy rule for .java files!");
+                }
+                suffix_rules.put(s, javac_state.getCopier());
+            }
+        }
+    }
+
+    /**
+     * Rewrite a / separated path into \ separated, but only
+     * if we are running on a platform were File.separatorChar=='\', ie winapi.
+     */
+    private String fixupSeparator(String p) {
+        if (File.separatorChar == '/') return p;
+        return p.replaceAll("/", "\\\\");
+    }
+
+    /**
+     * Scan the arguments for -i -x -xf -if followed by the option
+     * -src, -sourcepath, -modulepath or -classpath and produce a map of all the
+     * files to referenced for that particular option.
+     *
+     * Store the found sources and the found modules in the supplied maps.
+     */
+    private boolean findFiles(String[] args, String option, Set<String> suffixes,
+                              Map<String,Source> found_files, Map<String, Module> found_modules,
+                              Module current_module, boolean inLinksrc)
+        throws ProblemException, ProblemException
+    {
+        // Track which source roots, source path roots and class path roots have been added.
+        Set<File> roots = new HashSet<File>();
+        // Track the current set of package includes,excludes as well as excluded source files,
+        // to be used in the next -src/-sourcepath/-classpath
+        List<String> includes = new LinkedList<String>();
+        List<String> excludes = new LinkedList<String>();
+        List<String> excludefiles = new LinkedList<String>();
+        List<String> includefiles = new LinkedList<String>();
+        // This include is used to find all modules in the source.
+        List<String> moduleinfo = new LinkedList<String>();
+        moduleinfo.add("module-info.java");
+
+        for (int i = 0; i<args.length; ++i) {
+            if (args[i].equals("-i")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a package pattern following -i");
+                }
+                String incl = args[i+1];
+                checkPattern(incl);
+                includes.add(incl);
+            }
+            if (args[i].equals("-x")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a package pattern following -x");
+                }
+                String excl = args[i+1];
+                checkPattern(excl);
+                excludes.add(excl);
+            }
+            if (args[i].equals("-xf")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a file following -xf");
+                }
+                String exclf = args[i+1];
+                checkFilePattern(exclf);
+                exclf = Util.normalizeDriveLetter(exclf);
+                excludefiles.add(fixupSeparator(exclf));
+            }
+            if (args[i].equals("-if")) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a file following -xf");
+                }
+                String inclf = args[i+1];
+                checkFilePattern(inclf);
+                inclf = Util.normalizeDriveLetter(inclf);
+                includefiles.add(fixupSeparator(inclf));
+            }
+            if (args[i].equals(option)) {
+                if (i+1 >= args.length) {
+                    throw new ProblemException("You have to specify a directory following "+option);
+                }
+                String[] root_dirs = args[i+1].split(File.pathSeparator);
+                for (String r : root_dirs) {
+                    File root = new File(r);
+                    if (!root.isDirectory()) {
+                        throw new ProblemException("\""+r+"\" is not a directory.");
+                    }
+                    try {
+                        root = root.getCanonicalFile();
+                    } catch (IOException e) {
+                        throw new ProblemException(""+e);
+                    }
+                    if (roots.contains(root)) {
+                        throw new ProblemException("\""+r+"\" has already been used for "+option);
+                    }
+                    if (roots.equals(bin_dir)) {
+                        throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d");
+                    }
+                    if (roots.equals(gensrc_dir)) {
+                        throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s");
+                    }
+                    if (roots.equals(header_dir)) {
+                        throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h");
+                    }
+                    roots.add(root);
+                    Source.scanRoot(root, suffixes, excludes, includes, excludefiles, includefiles,
+                                    found_files, found_modules, current_module,
+                                    findBooleanOption(args, "--permit-sources-without-package"),
+                                    false, inLinksrc);
+                }
+            }
+            if (args[i].equals("-src") ||
+                args[i].equals("-sourcepath") ||
+                args[i].equals("-modulepath") ||
+                args[i].equals("-classpath"))
+            {
+                // Reset the includes,excludes and excludefiles after they have been used.
+                includes = new LinkedList<String>();
+                excludes = new LinkedList<String>();
+                excludefiles = new LinkedList<String>();
+                includefiles = new LinkedList<String>();
+            }
+        }
+        return true;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Module.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The module is the root of a set of packages/sources/artifacts.
+ * At the moment there is only one module in use, the empty/no-name/default module.
+ *
+ * <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></p>
+ */
+public class Module implements Comparable<Module> {
+    private String name;
+    private String dirname;
+    private Map<String,Package> packages = new HashMap<String,Package>();
+    private Map<String,Source> sources = new HashMap<String,Source>();
+    private Map<String,File> artifacts = new HashMap<String,File>();
+
+    public Module(String n, String dn) {
+        name = n;
+        dirname = n;
+    }
+
+    public String name() { return name; }
+    public String dirname() { return dirname; }
+    public Map<String,Package> packages() { return packages; }
+    public Map<String,Source> sources() { return sources; }
+    public Map<String,File> artifacts() { return artifacts; }
+
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof Module) && name.equals(((Module)o).name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public int compareTo(Module o) {
+        return name.compareTo(o.name);
+    }
+
+    public void save(StringBuilder b) {
+        b.append("M ").append(name).append(":").append("\n");
+        Package.savePackages(packages, b);
+    }
+
+    public static Module load(String l) {
+        int cp = l.indexOf(':',2);
+        if (cp == -1) return null;
+        String name = l.substring(2,cp);
+        return new Module(name, "");
+    }
+
+    public static void saveModules(Map<String,Module> ms, StringBuilder b)
+    {
+        for (Module m : ms.values()) {
+            m.save(b);
+        }
+    }
+
+    public void addPackage(Package p) {
+        packages.put(p.name(), p);
+    }
+
+    public Package lookupPackage(String pkg) {
+        Package p = packages.get(pkg);
+        if (p == null) {
+            p = new Package(this, pkg);
+            packages.put(pkg, p);
+        }
+        return p;
+    }
+
+    public void addSource(String pkg, Source src) {
+        Package p = lookupPackage(pkg);
+        src.setPackage(p);
+        p.addSource(src);
+        sources.put(src.file().getPath(), src);
+    }
+
+    public Source lookupSource(String path) {
+        return sources.get(path);
+    }
+
+    public void addArtifacts(String pkg, Set<URI> as) {
+        Package p = lookupPackage(pkg);
+        for (URI u : as) {
+            p.addArtifact(new File(u));
+        }
+    }
+
+    public void setDependencies(String pkg, Set<String> deps) {
+        Package p = lookupPackage(pkg);
+        p.setDependencies(deps);
+    }
+
+    public void setPubapi(String pkg, List<String> ps) {
+        Package p = lookupPackage(pkg);
+        p.setPubapi(ps);
+    }
+
+    public boolean hasPubapiChanged(String pkg, List<String> ps) {
+        Package p = lookupPackage(pkg);
+        return p.hasPubapiChanged(ps);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Package.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The Package class maintains meta information about a package.
+ * For example its sources, dependents,its pubapi and its artifacts.
+ *
+ * It might look odd that we track dependents/pubapi/artifacts on
+ * a package level, but it makes sense since recompiling a full package
+ * takes as long as recompiling a single java file in that package,
+ * if you take into account the startup time of the jvm.
+ *
+ * Also the dependency information will be much smaller (good for the javac_state file size)
+ * and it simplifies tracking artifact generation, you do not always know from which
+ * source a class file was generated, but you always know which package it belongs to.
+ *
+ * It is also educational to see package dependencies triggering recompilation of
+ * other packages. Even though the recompilation was perhaps not necessary,
+ * the visible recompilation of the dependent packages indicates how much circular
+ * dependencies your code has.
+ *
+ * <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></p>
+ */
+public class Package implements Comparable<Package> {
+    // The module this package belongs to. (There is a legacy module with an empty string name,
+    // used for all legacy sources.)
+    private Module mod;
+    // Name of this package, module:pkg
+    // ex1 jdk.base:java.lang
+    // ex2 :java.lang (when in legacy mode)
+    private String name;
+    // The directory path to the package. If the package belongs to a module,
+    // then that module's file system name is part of the path.
+    private String dirname;
+    // This package depends on these packages.
+    private Set<String> dependencies = new HashSet<String>();
+    // This package has the following dependents, that depend on this package.
+    private Set<String> dependents = new HashSet<String>();
+    // This is the public api of this package.
+    private List<String> pubapi = new ArrayList<String>();
+    // Map from source file name to Source info object.
+    private Map<String,Source> sources = new HashMap<String,Source>();
+    // This package generated these artifacts.
+    private Map<String,File> artifacts = new HashMap<String,File>();
+
+    public Package(Module m, String n) {
+        int c = n.indexOf(":");
+        assert(c != -1);
+        String mn = n.substring(0,c);
+        assert(m.name().equals(m.name()));
+        name = n;
+        dirname = n.replace('.', File.separatorChar);
+        if (m.name().length() > 0) {
+            // There is a module here, prefix the module dir name to the path.
+            dirname = m.dirname()+File.separatorChar+dirname;
+        }
+    }
+
+    public Module mod() { return mod; }
+    public String name() { return name; }
+    public String dirname() { return dirname; }
+    public Map<String,Source> sources() { return sources; }
+    public Map<String,File> artifacts() { return artifacts; }
+    public List<String> pubapi() { return pubapi; }
+
+    public Set<String> dependencies() { return dependencies; }
+    public Set<String> dependents() { return dependents; }
+
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof Package) && name.equals(((Package)o).name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public int compareTo(Package o) {
+        return name.compareTo(o.name);
+    }
+
+    public void addSource(Source s) {
+        sources.put(s.file().getPath(), s);
+    }
+
+    public void addDependency(String d) {
+        dependencies.add(d);
+    }
+
+    public void addDependent(String d) {
+        dependents.add(d);
+    }
+
+    public void addPubapi(String p) {
+        pubapi.add(p);
+    }
+
+    /**
+     * Check if we have knowledge in the javac state that
+     * describe the results of compiling this package before.
+     */
+    public boolean existsInJavacState() {
+        return artifacts.size() > 0 || pubapi.size() > 0;
+    }
+
+    public static List<String> pubapiToList(String ps)
+    {
+        String[] lines = ps.split("\n");
+        List<String> r = new ArrayList<String>();
+        for (String l : lines) {
+            r.add(l);
+        }
+        return r;
+    }
+
+    public boolean hasPubapiChanged(List<String> ps) {
+        Iterator<String> i = ps.iterator();
+        Iterator<String> j = pubapi.iterator();
+        int line = 0;
+        while (i.hasNext() && j.hasNext()) {
+            String is = i.next();
+            String js = j.next();
+            if (!is.equals(js)) {
+                Log.debug("Change in pubapi for package "+name+" line "+line);
+                Log.debug("Old: "+js);
+                Log.debug("New: "+is);
+                return true;
+            }
+            line++;
+        }
+        if ((i.hasNext() && !j.hasNext() ) ||
+            (!i.hasNext() && j.hasNext())) {
+            Log.debug("Change in pubapi for package "+name);
+            if (i.hasNext()) {
+                Log.debug("New has more lines!");
+            } else {
+                Log.debug("Old has more lines!");
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public void setPubapi(List<String> ps) {
+        pubapi = ps;
+    }
+
+    public void setDependencies(Set<String> ds) {
+        dependencies = ds;
+    }
+
+    public void save(StringBuilder b) {
+        b.append("P ").append(name).append("\n");
+        Source.saveSources(sources, b);
+        saveDependencies(b);
+        savePubapi(b);
+        saveArtifacts(b);
+    }
+
+    static public Package load(Module module, String l) {
+        String name = l.substring(2);
+        return new Package(module, name);
+    }
+
+    public void loadDependency(String l) {
+        String n = l.substring(2);
+        addDependency(n);
+    }
+
+    public void loadPubapi(String l) {
+        String pi = l.substring(2);
+        addPubapi(pi);
+    }
+
+    public void saveDependencies(StringBuilder b) {
+        List<String> sorted_dependencies = new ArrayList<String>();
+        for (String key : dependencies) {
+            sorted_dependencies.add(key);
+        }
+        Collections.sort(sorted_dependencies);
+        for (String a : sorted_dependencies) {
+            b.append("D "+a+"\n");
+        }
+    }
+
+    public void savePubapi(StringBuilder b) {
+        for (String l : pubapi) {
+            b.append("I "+l+"\n");
+        }
+    }
+
+    public static void savePackages(Map<String,Package> packages, StringBuilder b) {
+        List<String> sorted_packages = new ArrayList<String>();
+        for (String key : packages.keySet() ) {
+            sorted_packages.add(key);
+        }
+        Collections.sort(sorted_packages);
+        for (String s : sorted_packages) {
+            Package p = packages.get(s);
+            p.save(b);
+        }
+    }
+
+    public void addArtifact(String a) {
+        artifacts.put(a, new File(a));
+    }
+
+    public void addArtifact(File f) {
+        artifacts.put(f.getPath(), f);
+    }
+
+    public void addArtifacts(Set<URI> as) {
+        for (URI u : as) {
+            addArtifact(new File(u));
+        }
+    }
+
+    public void setArtifacts(Set<URI> as) {
+        assert(!artifacts.isEmpty());
+        artifacts = new HashMap<String,File>();
+        addArtifacts(as);
+    }
+
+    public void loadArtifact(String l) {
+        // Find next space after "A ".
+        int dp = l.indexOf(' ',2);
+        String fn = l.substring(2,dp);
+        long last_modified = Long.parseLong(l.substring(dp+1));
+        File f = new File(fn);
+        if (f.exists() && f.lastModified() != last_modified) {
+            // Hmm, the artifact on disk does not have the same last modified
+            // timestamp as the information from the build database.
+            // We no longer trust the artifact on disk. Delete it.
+            // The smart javac wrapper will then rebuild the artifact.
+            Log.debug("Removing "+f.getPath()+" since its timestamp does not match javac_state.");
+            f.delete();
+        }
+        artifacts.put(f.getPath(), f);
+    }
+
+    public void saveArtifacts(StringBuilder b) {
+        List<File> sorted_artifacts = new ArrayList<File>();
+        for (File f : artifacts.values()) {
+            sorted_artifacts.add(f);
+        }
+        Collections.sort(sorted_artifacts);
+        for (File f : sorted_artifacts) {
+            // The last modified information is only used
+            // to detect tampering with the output dir.
+            // If the outputdir has been modified, not by javac,
+            // then a mismatch will be detected in the last modified
+            // timestamps stored in the build database compared
+            // to the timestamps on disk and the artifact will be deleted.
+
+            b.append("A "+f.getPath()+" "+f.lastModified()+"\n");
+        }
+    }
+
+    /**
+     * Always clean out a tainted package before it is recompiled.
+     */
+    public void deleteArtifacts() {
+        for (File a : artifacts.values()) {
+            a.delete();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/ProblemException.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.sjavac;
+
+/**
+ * Used to signal serious problems when running sjavac.
+ *
+ * <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></p>
+ */
+public class ProblemException extends Exception {
+    static final long serialVersionUID = -3387516993124229949L;
+    public ProblemException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.Set;
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+/** A Source object maintains information about a source file.
+ * For example which package it belongs to and kind of source it is.
+ * The class also knows how to find source files (scanRoot) given include/exclude
+ * patterns and a root.
+ *
+ * <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></p>
+ */
+public class Source implements Comparable<Source> {
+    // The package the source belongs to.
+   private Package pkg;
+    // Name of this source file, relative its source root.
+    // For example: java/lang/Object.java
+    // Or if the source file is inside a module:
+    // jdk.base/java/lang/Object.java
+    private String name;
+    // What kind of file is this.
+    private String suffix;
+    // When this source file was last_modified
+    private long lastModified;
+    // The source File.
+    private File file;
+    // The source root under which file resides.
+    private File root;
+    // If the source is generated.
+    private boolean isGenerated;
+    // If the source is only linked to, not compiled.
+    private boolean linkedOnly;
+
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof Source) && name.equals(((Source)o).name);
+    }
+
+    @Override
+    public int compareTo(Source o) {
+        return name.compareTo(o.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    public Source(Module m, String n, File f, File r) {
+        name = n;
+        int dp = n.lastIndexOf(".");
+        if (dp != -1) {
+            suffix = n.substring(dp);
+        } else {
+            suffix = "";
+        }
+        file = f;
+        root = r;
+        lastModified = f.lastModified();
+        linkedOnly = false;
+    }
+
+    public Source(Package p, String n, long lm) {
+        pkg = p;
+        name = n;
+        int dp = n.lastIndexOf(".");
+        if (dp != -1) {
+            suffix = n.substring(dp);
+        } else {
+            suffix = "";
+        }
+        file = null;
+        root = null;
+        lastModified = lm;
+        linkedOnly = false;
+        int ls = n.lastIndexOf('/');
+    }
+
+    public String name() { return name; }
+    public String suffix() { return suffix; }
+    public Package pkg() { return pkg; }
+    public File   file() { return file; }
+    public File   root() { return root; }
+    public long lastModified() {
+        return lastModified;
+    }
+
+    public void setPackage(Package p) {
+        pkg = p;
+    }
+
+    public void markAsGenerated() {
+        isGenerated = true;
+    }
+
+    public boolean isGenerated() {
+        return isGenerated;
+    }
+
+    public void markAsLinkedOnly() {
+        linkedOnly = true;
+    }
+
+    public boolean isLinkedOnly() {
+        return linkedOnly;
+    }
+
+    private void save(StringBuilder b) {
+        String CL = linkedOnly?"L":"C";
+        String GS = isGenerated?"G":"S";
+        b.append(GS+" "+CL+" "+name+" "+file.lastModified()+"\n");
+    }
+    // Parse a line that looks like this:
+    // S C /code/alfa/A.java 1357631228000
+    static public Source load(Package lastPackage, String l, boolean isGenerated) {
+        int sp = l.indexOf(' ',4);
+        if (sp == -1) return null;
+        String name = l.substring(4,sp);
+        long last_modified = Long.parseLong(l.substring(sp+1));
+
+        boolean isLinkedOnly = false;
+        if (l.charAt(2) == 'L') {
+            isLinkedOnly = true;
+        } else if (l.charAt(2) == 'C') {
+            isLinkedOnly = false;
+        } else return null;
+
+        Source s = new Source(lastPackage, name, last_modified);
+        s.file = new File(name);
+        if (isGenerated) s.markAsGenerated();
+        if (isLinkedOnly) s.markAsLinkedOnly();
+        return s;
+    }
+
+    public static void saveSources(Map<String,Source> sources, StringBuilder b) {
+        List<String> sorted_sources = new ArrayList<String>();
+        for (String key : sources.keySet()) {
+            sorted_sources.add(key);
+        }
+        Collections.sort(sorted_sources);
+        for (String key : sorted_sources) {
+            Source s = sources.get(key);
+            s.save(b);
+        }
+    }
+
+    /**
+     * Recurse into the directory root and find all files matchine the excl/incl/exclfiles/inclfiles rules.
+     * Detects the existence of module-info.java files and presumes that the directory it resides in
+     * is the name of the current module.
+     */
+    static public void scanRoot(File root,
+                                Set<String> suffixes,
+                                List<String> excludes, List<String> includes,
+                                List<String> excludeFiles, List<String> includeFiles,
+                                Map<String,Source> foundFiles,
+                                Map<String,Module> foundModules,
+                                Module currentModule,
+                                boolean permitSourcesWithoutPackage,
+                                boolean inGensrc,
+                                boolean inLinksrc)
+        throws ProblemException {
+
+        if (root == null) return;
+        int root_prefix = root.getPath().length()+1;
+        // This is the root source directory, it must not contain any Java sources files
+        // because we do not allow Java source files without a package.
+        // (Unless of course --permit-sources-without-package has been specified.)
+        // It might contain other source files however, (for -tr and -copy) these will
+        // always be included, since no package pattern can match the root directory.
+        currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
+                                       excludeFiles, includeFiles, false,
+                                       foundFiles, foundModules, currentModule,
+                                       inGensrc, inLinksrc);
+
+        File[] dirfiles = root.listFiles();
+        for (File d : dirfiles) {
+            if (d.isDirectory()) {
+                // Descend into the directory structure.
+                scanDirectory(d, root_prefix, root, suffixes,
+                              excludes, includes, excludeFiles, includeFiles,
+                              false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+            }
+        }
+    }
+
+    /**
+     * Test if a path matches any of the patterns given.
+     * The pattern foo.bar matches only foo.bar
+     * The pattern foo.* matches foo.bar and foo.bar.zoo etc
+     */
+    static private boolean hasMatch(String path, List<String> patterns) {
+        for (String p : patterns) {
+            // Exact match
+            if (p.equals(path)) {
+                return true;
+            }
+            // Single dot the end matches this package and all its subpackages.
+            if (p.endsWith(".*")) {
+                // Remove the wildcard
+                String patprefix = p.substring(0,p.length()-2);
+                // Does the path start with the pattern prefix?
+                if (path.startsWith(patprefix)) {
+                    // If the path has the same length as the pattern prefix, then it is a match.
+                    // If the path is longer, then make sure that
+                    // the next part of the path starts with a dot (.) to prevent
+                    // wildcard matching in the middle of a package name.
+                    if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Matches patterns with the asterisk first. */
+     // The pattern foo/bar.java only matches foo/bar.java
+     // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
+    static private boolean hasFileMatch(String path, List<String> patterns) {
+        path = Util.normalizeDriveLetter(path);
+        for (String p : patterns) {
+            // Exact match
+            if (p.equals(path)) {
+                return true;
+            }
+            // Single dot the end matches this package and all its subpackages.
+            if (p.startsWith("*")) {
+                // Remove the wildcard
+                String patsuffix = p.substring(1);
+                // Does the path start with the pattern prefix?
+                if (path.endsWith(patsuffix)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add the files in the directory, assuming that the file has not been excluded.
+     * Returns a fresh Module object, if this was a dir with a module-info.java file.
+     */
+    static private Module addFilesInDir(File dir, int rootPrefix, File root,
+                                        Set<String> suffixes, boolean allow_javas,
+                                        List<String> excludeFiles, List<String> includeFiles, boolean all,
+                                        Map<String,Source> foundFiles,
+                                        Map<String,Module> foundModules,
+                                        Module currentModule,
+                                        boolean inGensrc,
+                                        boolean inLinksrc)
+        throws ProblemException
+    {
+        for (File f : dir.listFiles()) {
+            if (f.isFile()) {
+                boolean should_add =
+                    (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
+                    && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
+
+                if (should_add) {
+                    if (!allow_javas && f.getName().endsWith(".java")) {
+                        throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
+                                                   ", please remove "+f.getName());
+                    }
+                    // Extract the file name relative the root.
+                    String fn = f.getPath().substring(rootPrefix);
+                    // Extract the package name.
+                    int sp = fn.lastIndexOf(File.separatorChar);
+                    String pkg = "";
+                    if (sp != -1) {
+                        pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
+                    }
+                    // Is this a module-info.java file?
+                    if (fn.endsWith("module-info.java")) {
+                        // Aha! We have recursed into a module!
+                        if (!currentModule.name().equals("")) {
+                            throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
+                        }
+                        String module_name = fn.substring(0,fn.length()-16);
+                        currentModule = new Module(module_name, f.getPath());
+                        foundModules.put(module_name, currentModule);
+                    }
+                    // Extract the suffix.
+                    int dp = fn.lastIndexOf(".");
+                    String suffix = "";
+                    if (dp > 0) {
+                        suffix = fn.substring(dp);
+                    }
+                    // Should the file be added?
+                    if (all || suffixes.contains(suffix)) {
+                        Source of = foundFiles.get(f.getPath());
+                        if (of != null) {
+                            throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
+                        }
+                        of = currentModule.lookupSource(f.getPath());
+                        if (of != null) {
+                            // Oups, the source is already added, could be ok, could be not, lets check.
+                            if (inLinksrc) {
+                                // So we are collecting sources for linking only.
+                                if (of.isLinkedOnly()) {
+                                    // Ouch, this one is also for linking only. Bad.
+                                    throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
+                                }
+                                // Ok, the existing source is to be compiled. Thus this link only is redundant
+                                // since all compiled are also linked to. Continue to the next source.
+                                // But we need to add the source, so that it will be visible to linking,
+                                // if not the multi core compile will fail because a JavaCompiler cannot
+                                // find the necessary dependencies for its part of the source.
+                                foundFiles.put(f.getPath(), of);
+                                continue;
+                            } else {
+                                // We are looking for sources to compile, if we find an existing to be compiled
+                                // source with the same name, it is an internal error, since we must
+                                // find the sources to be compiled before we find the sources to be linked to.
+                                throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
+                            }
+                        }
+                        Source s = new Source(currentModule, f.getPath(), f, root);
+                        if (inGensrc) s.markAsGenerated();
+                        if (inLinksrc) {
+                            s.markAsLinkedOnly();
+                        }
+                        pkg = currentModule.name()+":"+pkg;
+                        foundFiles.put(f.getPath(), s);
+                        currentModule.addSource(pkg, s);
+                    }
+                }
+            }
+        }
+        return currentModule;
+    }
+
+    private static boolean gurka = false;
+
+    static private void scanDirectory(File dir, int rootPrefix, File root,
+                                      Set<String> suffixes,
+                                      List<String> excludes, List<String> includes,
+                                      List<String> excludeFiles, List<String> includeFiles, boolean all,
+                                      Map<String,Source> foundFiles,
+                                      Map<String,Module> foundModules,
+                                      Module currentModule, boolean inGensrc, boolean inLinksrc)
+        throws ProblemException {
+
+        String pkg_name = "";
+        // Remove the root prefix from the dir path, and replace file separator with dots
+        // to get the package name.
+        if (dir.getPath().length() > rootPrefix) {
+            pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.');
+        }
+        // Should this package directory be included and not excluded?
+        if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) &&
+                    (excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) {
+            // Add the source files.
+            currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all,
+                                          foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+        }
+
+        for (File d : dir.listFiles()) {
+            if (d.isDirectory()) {
+                // Descend into the directory structure.
+                scanDirectory(d, rootPrefix, root, suffixes,
+                              excludes, includes, excludeFiles, includeFiles, all,
+                              foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.PrintStream;
+import java.net.URI;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * The transform interface is used to transform content inside a package, from one form to another.
+ * Usually the output form is an unpredictable number of output files. (eg class files)
+ * but can also be an unpredictable number of generated source files (eg idl2java)
+ * or a single predictable output file (eg when copying,cleaning or compiling a properties file).
+ *
+ * <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></p>
+ */
+public interface Transformer
+{
+    /**
+     * The transform method takes a set of package names, mapped to their source files and to the
+     * pubapis of the packages.
+     *
+     * The transform implementation must:
+     *    store the names of the generated artifacts for each package into package_artifacts
+     *    store found dependencies to other packages into the supplied set package_dependencies
+     *    store the public api for a package into the supplied set package_pubapis
+     *
+     * Any benign messages as a result of running the transform
+     * are written into stdout, and errors are written to stderr.
+     *
+     * The debug_level can be 0=silent (only warnings and errors) 1=normal 2=verbose 3 or greater=debug
+     * setExtra is used to set the extra information information that can be passed on
+     * the command line to the smart javac wrapper.
+     *
+     * If sjavac is building incrementally from an existing javac_state, the var incremental is true.
+     *
+     * The transformer will only be called if some source in the package (or dependency) has
+     * a modified timestamp. Thus the transformer might get called with many sources, of which
+     * only one has changed. The transformer is allowed to regenerate all artifacts but
+     * a better transformer will only write those artifacts that need updating.
+     *
+     * However the transformer must verify that the existing artifacts really are there!
+     * and it must always update package_artifacts, package_dependencies, and package_pubapis correctly.
+     * This means that at least for Java source, it will always have to recompile the sources.
+     *
+     * The transformer is allowed to put files anywhere in the dest_root.
+     * An example of this is, can be the META-INF transformer that copy files
+     * below META-INF directories to the single META-INF directory below dest_root.
+     *
+     * False is returned if there was an error that prevented the transform.
+     * I.e. something was printed on stderr.
+     *
+     * If num_cores is set to a non-zero value. The transform should attempt to use no more than these
+     * number of threads for heavy work.
+     */
+    boolean transform(Map<String,Set<URI>> pkgSrcs,
+                      Set<URI>             visibleSources,
+                      Map<URI,Set<String>> visibleClasses,
+                      Map<String,Set<String>> oldPackageDependencies,
+                      URI destRoot,
+                      Map<String,Set<URI>>    packageArtifacts,
+                      Map<String,Set<String>> packageDependencies,
+                      Map<String,String>      packagePublicApis,
+                      int debugLevel,
+                      boolean incremental,
+                      int numCores,
+                      PrintStream out,
+                      PrintStream err);
+
+    void setExtra(String e);
+    void setExtra(String[] args);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Utilities.
+ *
+ * <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></p>
+ */
+public class Util {
+
+    public static String toFileSystemPath(String pkgId) {
+        if (pkgId == null || pkgId.length()==0) return null;
+        String pn;
+        if (pkgId.charAt(0) == ':') {
+            // When the module is the default empty module.
+            // Do not prepend the module directory, because there is none.
+            // Thus :java.foo.bar translates to java/foo/bar (or \)
+            pn = pkgId.substring(1).replace('.',File.separatorChar);
+        } else {
+            // There is a module. Thus jdk.base:java.foo.bar translates
+            // into jdk.base/java/foo/bar
+            int cp = pkgId.indexOf(':');
+            String mn = pkgId.substring(0,cp);
+            pn = mn+File.separatorChar+pkgId.substring(cp+1).replace('.',File.separatorChar);
+        }
+        return pn;
+    }
+
+    public static String justPackageName(String pkgName) {
+        int c = pkgName.indexOf(":");
+        assert(c != -1);
+        return pkgName.substring(c+1);
+    }
+
+    public static String extractStringOption(String opName, String s) {
+        int p = s.indexOf(opName+"=");
+        if (p == -1) return null;
+        p+=opName.length()+1;
+        int pe = s.indexOf(',', p);
+        if (pe == -1) pe = s.length();
+        return s.substring(p, pe);
+    }
+
+    public static int extractIntOption(String opName, String s) {
+        int p = s.indexOf(opName+"=");
+        if (p == -1) return 0;
+        p+=opName.length()+1;
+        int pe = s.indexOf(',', p);
+        if (pe == -1) pe = s.length();
+        int v = 0;
+        try {
+            v = Integer.parseInt(s.substring(p, pe));
+        } catch (Exception e) {}
+        return v;
+    }
+
+    /**
+     * Clean out unwanted sub options supplied inside a primary option.
+     * For example to only had portfile remaining from:
+     *    settings="--server:id=foo,portfile=bar"
+     * do settings = cleanOptions("--server:",Util.set("-portfile"),settings);
+     *    now settings equals "--server:portfile=bar"
+     *
+     * @param optionPrefix The option name, including colon, eg --server:
+     * @param allowsSubOptions A set of the allowed sub options, id portfile etc.
+     * @param s The option settings string.
+     */
+    public static String cleanSubOptions(String optionPrefix, Set<String> allowedSubOptions, String s) {
+        StringBuilder sb = new StringBuilder();
+        if (!s.startsWith(optionPrefix)) return "";
+        StringTokenizer st = new StringTokenizer(s.substring(optionPrefix.length()), ",");
+        while (st.hasMoreTokens()) {
+            String o = st.nextToken();
+            int p = o.indexOf('=');
+            if (p>0) {
+                String key = o.substring(0,p);
+                String val = o.substring(p+1);
+                if (allowedSubOptions.contains(key)) {
+                    if (sb.length() > 0) sb.append(',');
+                    sb.append(key+"="+val);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Convenience method to create a set with strings.
+     */
+    public static Set<String> set(String... ss) {
+        Set<String> set = new HashSet<String>();
+        set.addAll(Arrays.asList(ss));
+        return set;
+    }
+
+    /**
+     * Normalize windows drive letter paths to upper case to enable string
+     * comparison.
+     *
+     * @param file File name to normalize
+     * @return The normalized string if file has a drive letter at the beginning,
+     *         otherwise the original string.
+     */
+    public static String normalizeDriveLetter(String file) {
+        if (file.length() > 2 && file.charAt(1) == ':') {
+            return Character.toUpperCase(file.charAt(0)) + file.substring(1);
+        } else if (file.length() > 3 && file.charAt(0) == '*'
+                   && file.charAt(2) == ':') {
+            // Handle a wildcard * at the beginning of the string.
+            return file.substring(0, 1) + Character.toUpperCase(file.charAt(1))
+                   + file.substring(2);
+        }
+        return file;
+    }
+
+    /**
+     * Locate the setting for the server properties.
+     */
+    public static String findServerSettings(String[] args) {
+        for (String s : args) {
+            if (s.startsWith("--server:")) {
+                return s;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.sjavac.comp;
+
+import javax.lang.model.element.Element;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+
+/** Utility class containing dependency information between packages
+ *  and the pubapi for a package.
+ *
+ * <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></p>
+ */
+public class Dependencies {
+    protected static final Context.Key<Dependencies> dependenciesKey =
+        new Context.Key<Dependencies>();
+
+    // The log to be used for error reporting.
+    protected Log log;
+    // Map from package name to packages that the package depends upon.
+    protected Map<Name,Set<Name>> deps;
+    // This is the set of all packages that are supplied
+    // through the java files at the command line.
+    protected Set<Name> explicitPackages;
+
+    // Map from a package name to its public api.
+    // Will the Name encode the module in the future?
+    // If not, this will have to change to map from Module+Name to public api.
+    protected Map<Name,StringBuffer> publicApiPerClass;
+
+    public static Dependencies instance(Context context) {
+        Dependencies instance = context.get(dependenciesKey);
+        if (instance == null)
+            instance = new Dependencies(context);
+        return instance;
+    }
+
+    private Dependencies(Context context) {
+        context.put(dependenciesKey, this);
+        log = Log.instance(context);
+    }
+
+    public void reset()
+    {
+        deps = new HashMap<Name, Set<Name>>();
+        explicitPackages = new HashSet<Name>();
+        publicApiPerClass = new HashMap<Name,StringBuffer>();
+    }
+
+    /**
+     * Fetch the set of dependencies that are relevant to the compile
+     * that has just been performed. I.e. we are only interested in
+     * dependencies for classes that were explicitly compiled.
+     * @return
+     */
+    public Map<String,Set<String>> getDependencies() {
+        Map<String,Set<String>> new_deps = new HashMap<String,Set<String>>();
+        if (explicitPackages == null) return new_deps;
+        for (Name pkg : explicitPackages) {
+            Set<Name> set = deps.get(pkg);
+            if (set != null) {
+                Set<String> new_set = new_deps.get(pkg.toString());
+                if (new_set == null) {
+                    new_set = new HashSet<String>();
+                    // Modules beware....
+                    new_deps.put(":"+pkg.toString(), new_set);
+                }
+                for (Name d : set) {
+                    new_set.add(":"+d.toString());
+                }
+            }
+        }
+        return new_deps;
+    }
+
+    class CompareNames implements Comparator<Name> {
+         public int compare(Name a, Name b) {
+             return a.toString().compareTo(b.toString());
+         }
+
+         public boolean equals(Object obj) {
+             return super.equals(obj);
+         }
+    }
+
+    /**
+     * Convert the map from class names to their pubapi to a map
+     * from package names to their pubapi (which is the sorted concatenation
+     * of all the class pubapis)
+     */
+    public Map<String,String> getPubapis() {
+        Map<String,String> publicApiPerPackage = new HashMap<String,String>();
+        if (publicApiPerClass == null) return publicApiPerPackage;
+        Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]);
+        Arrays.sort(keys, new CompareNames());
+        StringBuffer newPublicApi = new StringBuffer();
+        int i=0;
+        String prevPkg = "";
+        for (Name k : keys) {
+            String cn = k.toString();
+            String pn = "";
+            int dp = cn.lastIndexOf('.');
+            if (dp != -1) {
+                pn = cn.substring(0,dp);
+            }
+            if (!pn.equals(prevPkg)) {
+                if (!prevPkg.equals("")) {
+                    // Add default module name ":"
+                    publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
+                }
+                newPublicApi = new StringBuffer();
+                prevPkg = pn;
+            }
+            newPublicApi.append(publicApiPerClass.get(k));
+            i++;
+        }
+        if (!prevPkg.equals(""))
+            publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
+        return publicApiPerPackage;
+    }
+
+    /**
+     * Visit the api of a class and construct a pubapi string and
+     * store it into the pubapi_perclass map.
+     */
+    public void visitPubapi(Element e) {
+        Name n = ((ClassSymbol)e).fullname;
+        Name p = ((ClassSymbol)e).packge().fullname;
+        StringBuffer sb = publicApiPerClass.get(n);
+        assert(sb == null);
+        sb = new StringBuffer();
+        PubapiVisitor v = new PubapiVisitor(sb);
+        v.visit(e);
+        if (sb.length()>0) {
+            publicApiPerClass.put(n, sb);
+        }
+        explicitPackages.add(p);
+     }
+
+    /**
+     * Collect a dependency. curr_pkg is marked as depending on dep_pkg.
+     */
+    public void collect(Name currPkg, Name depPkg) {
+        if (!currPkg.equals(depPkg)) {
+            Set<Name> theset = deps.get(currPkg);
+            if (theset==null) {
+                theset = new HashSet<Name>();
+                deps.put(currPkg, theset);
+            }
+            theset.add(depPkg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.util.StringTokenizer;
+
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.sjavac.server.CompilerThread;
+import java.io.File;
+
+/** Subclass to Resolve that overrides collect.
+ *
+ * <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></p>
+ */
+public class JavaCompilerWithDeps extends JavaCompiler {
+
+    /** The dependency database
+     */
+    protected Dependencies deps;
+    protected CompilerThread compilerThread;
+
+    public JavaCompilerWithDeps(Context context, CompilerThread t) {
+        super(context);
+        deps = Dependencies.instance(context);
+        compilerThread = t;
+        needRootClasses = true;
+    }
+
+    public static void preRegister(Context context, final CompilerThread t) {
+        context.put(compilerKey, new Context.Factory<JavaCompiler>() {
+            public JavaCompiler make(Context c) {
+                JavaCompiler instance = new JavaCompilerWithDeps(c, t);
+                c.put(JavaCompiler.class, instance);
+                return instance;
+            }
+        });
+    }
+
+    /** Collect the public apis of classes supplied explicitly for compilation.
+     * @param sym The class to visit.
+     */
+    @Override
+    public void reportPublicApi(ClassSymbol sym) {
+        // The next test will catch when source files are located in the wrong directory!
+        // This ought to be moved into javac as a new warning, or perhaps as part
+        // of the auxiliary class warning.
+
+        // For example if sun.swing.BeanInfoUtils
+        // is in fact stored in: /mybuild/jdk/gensrc/javax/swing/beaninfo/BeanInfoUtils.java
+
+        // We do not need to test that BeanInfoUtils is stored in a file named BeanInfoUtils
+        // since this is checked earlier.
+        if (sym.sourcefile != null) {
+            // Rewrite sun.swing.BeanInfoUtils into /sun/swing/
+            StringBuilder pathb = new StringBuilder();
+            StringTokenizer qn = new StringTokenizer(sym.packge().toString(), ".");
+            boolean first = true;
+            while (qn.hasMoreTokens()) {
+                String o = qn.nextToken();
+                pathb.append("/");
+                pathb.append(o);
+                first = false;
+            }
+            pathb.append("/");
+            String path = pathb.toString();
+
+            // Now cut the uri to be: file:///mybuild/jdk/gensrc/javax/swing/beaninfo/
+            String p = sym.sourcefile.toUri().getPath();
+            // Do not use File.separatorChar here, a URI always uses slashes /.
+            int i = p.lastIndexOf("/");
+            String pp = p.substring(0,i+1);
+
+            // Now check if the truncated uri ends with the path. (It does not == failure!)
+            if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
+                compilerThread.logError("Error: The source file "+sym.sourcefile.getName()+
+                                        " is located in the wrong package directory, because it contains the class "+
+                                        sym.getQualifiedName());
+            }
+        }
+        deps.visitPubapi(sym);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.sjavac.comp;
+
+import java.util.Iterator;
+import java.util.List;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementScanner6;
+
+/** Utility class that constructs a textual representation
+ * of the public api of a class.
+ *
+ * <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></p>
+ */
+public class PubapiVisitor extends ElementScanner6<Void, Void> {
+
+    StringBuffer sb;
+    // Important that it is 1! Part of protocol over wire, silly yes.
+    // Fix please.
+    int indent = 1;
+
+    public PubapiVisitor(StringBuffer sb) {
+        this.sb = sb;
+    }
+
+    String depth(int l) {
+        return "                                              ".substring(0, l);
+    }
+
+    @Override
+    public Void visitType(TypeElement e, Void p) {
+        if (e.getModifiers().contains(Modifier.PUBLIC)
+            || e.getModifiers().contains(Modifier.PROTECTED))
+        {
+            sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n");
+            indent += 2;
+            Void v = super.visitType(e, p);
+            indent -= 2;
+            return v;
+        }
+        return null;
+    }
+
+    @Override
+    public Void visitVariable(VariableElement e, Void p) {
+        if (e.getModifiers().contains(Modifier.PUBLIC)
+            || e.getModifiers().contains(Modifier.PROTECTED)) {
+            sb.append(depth(indent)).append("VAR ")
+                    .append(makeVariableString(e)).append("\n");
+        }
+        // Safe to not recurse here, because the only thing
+        // to visit here is the constructor of a variable declaration.
+        // If it happens to contain an anonymous inner class (which it might)
+        // then this class is never visible outside of the package anyway, so
+        // we are allowed to ignore it here.
+        return null;
+    }
+
+    @Override
+    public Void visitExecutable(ExecutableElement e, Void p) {
+        if (e.getModifiers().contains(Modifier.PUBLIC)
+            || e.getModifiers().contains(Modifier.PROTECTED)) {
+            sb.append(depth(indent)).append("METHOD ")
+                    .append(makeMethodString(e)).append("\n");
+        }
+        return null;
+    }
+
+    /**
+     * Creates a String representation of a method element with everything
+     * necessary to track all public aspects of it in an API.
+     * @param e Element to create String for.
+     * @return String representation of element.
+     */
+    protected String makeMethodString(ExecutableElement e) {
+        StringBuilder result = new StringBuilder();
+        for (Modifier modifier : e.getModifiers()) {
+            result.append(modifier.toString());
+            result.append(" ");
+        }
+        result.append(e.getReturnType().toString());
+        result.append(" ");
+        result.append(e.toString());
+
+        List<? extends TypeMirror> thrownTypes = e.getThrownTypes();
+        if (!thrownTypes.isEmpty()) {
+            result.append(" throws ");
+            for (Iterator<? extends TypeMirror> iterator = thrownTypes
+                    .iterator(); iterator.hasNext();) {
+                TypeMirror typeMirror = iterator.next();
+                result.append(typeMirror.toString());
+                if (iterator.hasNext()) {
+                    result.append(", ");
+                }
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * Creates a String representation of a variable element with everything
+     * necessary to track all public aspects of it in an API.
+     * @param e Element to create String for.
+     * @return String representation of element.
+     */
+    protected String makeVariableString(VariableElement e) {
+        StringBuilder result = new StringBuilder();
+        for (Modifier modifier : e.getModifiers()) {
+            result.append(modifier.toString());
+            result.append(" ");
+        }
+        result.append(e.asType().toString());
+        result.append(" ");
+        result.append(e.toString());
+        Object value = e.getConstantValue();
+        if (value != null) {
+            result.append(" = ");
+            if (e.asType().toString().equals("char")) {
+                int v = (int)value.toString().charAt(0);
+                result.append("'\\u"+Integer.toString(v,16)+"'");
+            } else {
+                result.append(value.toString());
+            }
+        }
+        return result.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Symbol;
+
+/** Subclass to Resolve that overrides collect.
+ *
+ * <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></p>
+ */
+public class ResolveWithDeps extends Resolve {
+
+    /** The dependency database
+     */
+    protected Dependencies deps;
+
+    protected ResolveWithDeps(Context context) {
+        super(context);
+        deps = Dependencies.instance(context);
+    }
+
+    public static void preRegister(Context context) {
+        context.put(resolveKey, new Context.Factory<Resolve>() {
+            public Resolve make(Context c) {
+                Resolve instance = new ResolveWithDeps(c);
+                c.put(Resolve.class, instance);
+                return instance;
+            }
+        });
+    }
+    /** Collect dependencies in the enclosing class
+     * @param from The enclosing class sym
+     * @param to   The enclosing classes references this sym.
+     * */
+    @Override
+    public void reportDependence(Symbol from, Symbol to) {
+        // Capture dependencies between the packages.
+        deps.collect(from.packge().fullname, to.packge().fullname);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import com.sun.tools.javac.util.ListBuffer;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import javax.tools.*;
+import javax.tools.JavaFileObject.Kind;
+
+/**
+ * Intercepts reads and writes to the file system to gather
+ * information about what artifacts are generated.
+ *
+ * Traps writes to certain files, if the content written is identical
+ * to the existing file.
+ *
+ * Can also blind out the filemanager from seeing certain files in the file system.
+ * Necessary to prevent javac from seeing some sources where the source path points.
+ *
+ * <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></p>
+ */
+public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+
+    // Set of sources that can be seen by javac.
+    Set<URI> visibleSources = new HashSet<URI>();
+    // Map from modulename:packagename to artifacts.
+    Map<String,Set<URI>> packageArtifacts = new HashMap<String,Set<URI>>();
+    // Where to print informational messages.
+    PrintWriter stdout;
+
+    public SmartFileManager(JavaFileManager fileManager) {
+        super(fileManager);
+    }
+
+    public void setVisibleSources(Set<URI> s) {
+        visibleSources = s;
+    }
+
+    public void cleanArtifacts() {
+        packageArtifacts = new HashMap<String,Set<URI>>();
+    }
+
+    public void setLog(PrintWriter pw) {
+        stdout = pw;
+    }
+
+    public Map<String,Set<URI>> getPackageArtifacts() {
+        return packageArtifacts;
+    }
+
+    @Override
+    public Iterable<JavaFileObject> list(Location location,
+                                         String packageName,
+                                         Set<Kind> kinds,
+                                         boolean recurse)
+        throws IOException
+    {
+        // Acquire the list of files.
+        Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
+        if (visibleSources.isEmpty()) {
+            return files;
+        }
+        // Now filter!
+        ListBuffer<JavaFileObject> filteredFiles = new ListBuffer<JavaFileObject>();
+        for (JavaFileObject f : files) {
+            URI uri = f.toUri();
+            String t = uri.toString();
+            if (t.startsWith("jar:")
+                || t.endsWith(".class")
+                || visibleSources.contains(uri))
+            {
+                filteredFiles.add(f);
+            }
+        }
+        return filteredFiles;
+    }
+
+    @Override
+    public boolean hasLocation(Location location) {
+        return super.hasLocation(location);
+    }
+
+    @Override
+    public JavaFileObject getJavaFileForInput(Location location,
+                                              String className,
+                                              Kind kind)
+        throws IOException
+    {
+        JavaFileObject file = super.getJavaFileForInput(location, className, kind);
+        if (file == null || visibleSources.isEmpty()) {
+            return file;
+        }
+
+        if (visibleSources.contains(file.toUri())) {
+            return file;
+        }
+        return null;
+    }
+
+    @Override
+    public JavaFileObject getJavaFileForOutput(Location location,
+                                               String className,
+                                               Kind kind,
+                                               FileObject sibling)
+        throws IOException
+    {
+        JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
+        if (file == null) return file;
+        int dp = className.lastIndexOf('.');
+        String pkg_name = "";
+        if (dp != -1) {
+            pkg_name = className.substring(0, dp);
+        }
+        // When modules are in use, then the mod_name might be something like "jdk_base"
+        String mod_name = "";
+        addArtifact(mod_name+":"+pkg_name, file.toUri());
+        return file;
+    }
+
+    @Override
+    public FileObject getFileForInput(Location location,
+                                      String packageName,
+                                      String relativeName)
+        throws IOException
+    {
+        FileObject file =  super.getFileForInput(location, packageName, relativeName);
+        if (file == null || visibleSources.isEmpty()) {
+            return file;
+        }
+
+        if (visibleSources.contains(file.toUri())) {
+            return file;
+        }
+        return null;
+    }
+
+    @Override
+    public FileObject getFileForOutput(Location location,
+                                       String packageName,
+                                       String relativeName,
+                                       FileObject sibling)
+        throws IOException
+    {
+        FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
+        if (file == null) return file;
+        if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
+                file instanceof JavaFileObject) {
+           file = new SmartFileObject((JavaFileObject)file, stdout);
+           packageName = ":" + packageNameFromFileName(relativeName);
+        }
+        if (packageName.equals("")) {
+            packageName = ":";
+        }
+        addArtifact(packageName, file.toUri());
+        return file;
+    }
+
+    private String packageNameFromFileName(String fn) {
+        StringBuilder sb = new StringBuilder();
+        int p = fn.indexOf('_'), pp = 0;
+        while (p != -1) {
+            if (sb.length() > 0) sb.append('.');
+            sb.append(fn.substring(pp,p));
+            if (p == fn.length()-1) break;
+            pp = p+1;
+            p = fn.indexOf('_',pp);
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public void flush() throws IOException {
+        super.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        super.close();
+    }
+
+    void addArtifact(String pkgName, URI art) {
+        Set<URI> s = packageArtifacts.get(pkgName);
+        if (s == null) {
+            s = new HashSet<URI>();
+            packageArtifacts.put(pkgName, s);
+        }
+        s.add(art);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import java.io.*;
+import java.net.URI;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
+import javax.tools.JavaFileObject;
+
+/**
+ * The SmartFileObject will return an outputstream that cache the written data
+ * and compare the new content with the old content on disk. Only if they differ,
+ * will the file be updated.
+ *
+ * <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></p>
+ */
+public class SmartFileObject implements JavaFileObject {
+
+    JavaFileObject file;
+    PrintWriter stdout;
+
+    public SmartFileObject(JavaFileObject r, PrintWriter pw) {
+        file = r;
+        stdout = pw;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        return file.equals(other);
+    }
+
+    @Override
+    public int hashCode() {
+        return file.hashCode();
+    }
+
+    public Kind getKind() {
+        return file.getKind();
+    }
+
+    public boolean isNameCompatible(String simpleName, Kind kind) {
+        return file.isNameCompatible(simpleName, kind);
+    }
+
+    public URI toUri() {
+        return file.toUri();
+    }
+
+    public String getName() {
+        return file.getName();
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return file.openInputStream();
+    }
+
+    public OutputStream openOutputStream() throws IOException {
+        return file.openOutputStream();
+    }
+
+    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+        return file.getCharContent(ignoreEncodingErrors);
+    }
+
+    static String lineseparator = System.getProperty("line.separator");
+
+    public Writer openWriter() throws IOException {
+        StringBuilder s = new StringBuilder();
+        try (BufferedReader r = new BufferedReader(file.openReader(true))) {
+            while (r.ready()) {
+                s.append(r.readLine()+lineseparator);
+            }
+        } catch (FileNotFoundException e) {
+            // Perfectly ok.
+        }
+        return new SmartWriter(file, s.toString(), file.getName(), stdout);
+    }
+
+    public long getLastModified() {
+        return file.getLastModified();
+    }
+
+    public boolean delete() {
+        return file.delete();
+    }
+
+    public Modifier getAccessLevel() {
+        return file.getAccessLevel();
+    }
+
+    public NestingKind getNestingKind() {
+        return file.getNestingKind();
+    }
+
+    public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+        return file.openReader(ignoreEncodingErrors);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.*;
+import javax.tools.JavaFileObject;
+
+/**
+ * The SmartWriter will cache the written data and when the writer is closed,
+ * then it will compare the cached data with the old_content string.
+ * If different, then it will write all the new content to the file.
+ * If not, the file is not touched.
+ *
+ *  <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></p>
+ */
+public class SmartWriter extends Writer {
+
+    String name;
+    JavaFileObject file;
+    String oldContent;
+    StringWriter newContent = new StringWriter();
+    PrintWriter stdout;
+    boolean closed;
+    public SmartWriter(JavaFileObject f, String s, String n, PrintWriter pw) {
+        name = n;
+        file = f;
+        oldContent = s;
+        newContent = new StringWriter();
+        stdout = pw;
+        closed = false;
+    }
+
+    public void write(char[] chars, int i, int i1)
+    {
+        newContent.write(chars, i, i1);
+    }
+
+    public void close() throws IOException {
+        if (closed) return;
+        closed = true;
+        String s = newContent.toString();
+        if (!oldContent.equals(s)) {
+            int p = file.getName().lastIndexOf(File.separatorChar);
+            try (Writer writer = file.openWriter()) {
+                writer.write(s);
+            }
+            stdout.println("Writing "+file.getName().substring(p+1));
+        }
+    }
+
+    public void flush() throws IOException {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerPool.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.Stack;
+import java.util.concurrent.Future;
+
+/** The compiler pool maintains compiler threads.
+ *
+ * <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></p>
+ */
+public class CompilerPool {
+    // The javac server that created this pool.
+    private JavacServer javacServer;
+    // A semaphore protecting the poolsize number of threads.
+    private Semaphore available;
+    // The stack of compiler threads.
+    private Stack<CompilerThread> compilers = new Stack<CompilerThread>();
+    // And the executor server to spawn threads.
+    private final ExecutorService executorPool;
+    // How many requests are active right now?
+    private int concurrentRequests = 0;
+    // When was the last request finished?
+    private long lastRequestFinished = 0;
+    // The total number of requests to this pool.
+    private int numRequests = 0;
+    // Protect access to the three above values.
+    private static final Object conc = new Object();
+
+    /**
+     * Return the javac server that this pool belongs to.
+     */
+    public JavacServer getJavacServer() {
+        return javacServer;
+    }
+
+    /**
+     * Return how many threads are running at this very moment.
+     */
+    public int numActiveRequests()
+    {
+        synchronized (conc) {
+            return concurrentRequests;
+        }
+    }
+
+    /**
+     * Return when the last request was finished.
+     * I.e. the pool has been idle since.
+     */
+    public long lastRequestFinished()
+    {
+        synchronized (conc) {
+            return lastRequestFinished;
+        }
+    }
+
+    /**
+     * Up the number of active requests.
+     */
+    public int startRequest() {
+        int n;
+        synchronized (conc) {
+            concurrentRequests++;
+            numRequests++;
+            n = numRequests;
+        }
+        return n;
+    }
+
+    /**
+     * Down the number of active requests. Return the current time.
+     */
+    public long stopRequest() {
+        synchronized (conc) {
+            concurrentRequests--;
+            lastRequestFinished = System.currentTimeMillis();
+        }
+        return lastRequestFinished;
+    }
+
+    /**
+     * Create a new compiler pool.
+     */
+    CompilerPool(int poolsize, JavacServer server) {
+        available = new Semaphore(poolsize, true);
+        javacServer = server;
+        executorPool = Executors.newFixedThreadPool(poolsize);
+        lastRequestFinished = System.currentTimeMillis();
+    }
+
+    /**
+     * Execute a compiler thread.
+     */
+    public void execute(CompilerThread ct) {
+        executorPool.execute(ct);
+    }
+
+    /**
+     * Execute a minor task, for example generating bytecodes and writing them to disk,
+     * that belong to a major compiler thread task.
+     */
+    public Future<?> executeSubtask(CompilerThread t, Runnable r) {
+        return executorPool.submit(r);
+    }
+
+    /**
+     * Shutdown the pool.
+     */
+    public void shutdown() {
+        executorPool.shutdown();
+    }
+
+    /**
+     * Acquire a compiler thread from the pool, or block until a thread is available.
+     * If the pools is empty, create a new thread, but never more than is "available".
+     */
+    public CompilerThread grabCompilerThread() throws InterruptedException {
+        available.acquire();
+        if (compilers.empty()) {
+            return new CompilerThread(this);
+        }
+        return compilers.pop();
+    }
+
+    /**
+     * Return the specified compiler thread to the pool.
+     */
+    public void returnCompilerThread(CompilerThread h) {
+        compilers.push(h);
+        available.release();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.concurrent.Future;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.BaseFileManager;
+import com.sun.tools.sjavac.comp.Dependencies;
+import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
+import com.sun.tools.sjavac.comp.SmartFileManager;
+import com.sun.tools.sjavac.comp.ResolveWithDeps;
+
+/**
+ * The compiler thread maintains a JavaCompiler instance and
+ * can receive a request from the client, perform the compilation
+ * requested and report back the results.
+ *
+ *  * <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></p>
+ */
+public class CompilerThread implements Runnable {
+    private JavacServer javacServer;
+    private CompilerPool compilerPool;
+    private List<Future<?>> subTasks;
+
+    // Communicating over this socket.
+    private Socket socket;
+
+    // The necessary classes to do a compilation.
+    private com.sun.tools.javac.api.JavacTool compiler;
+    private StandardJavaFileManager fileManager;
+    private BaseFileManager fileManagerBase;
+    private SmartFileManager smartFileManager;
+    private Context context;
+
+    // If true, then this thread is serving a request.
+    private boolean inUse = false;
+
+    CompilerThread(CompilerPool cp) {
+        compilerPool = cp;
+        javacServer = cp.getJavacServer();
+    }
+
+    /**
+     * Execute a minor task, for example generating bytecodes and writing them to disk,
+     * that belong to a major compiler thread task.
+     */
+    public synchronized void executeSubtask(Runnable r) {
+        subTasks.add(compilerPool.executeSubtask(this, r));
+    }
+
+    /**
+     * Count the number of active sub tasks.
+     */
+    public synchronized int numActiveSubTasks() {
+        int c = 0;
+        for (Future<?> f : subTasks) {
+            if (!f.isDone() && !f.isCancelled()) {
+                c++;
+            }
+        }
+        return c;
+    }
+
+    /**
+     * Use this socket for the upcoming request.
+     */
+    public void setSocket(Socket s) {
+        socket = s;
+    }
+
+    /**
+     * Prepare the compiler thread for use. It is not yet started.
+     * It will be started by the executor service.
+     */
+    public synchronized void use() {
+        assert(!inUse);
+        inUse = true;
+        compiler = com.sun.tools.javac.api.JavacTool.create();
+        fileManager = compiler.getStandardFileManager(null, null, null);
+        fileManagerBase = (BaseFileManager)fileManager;
+        smartFileManager = new SmartFileManager(fileManager);
+        context = new Context();
+        context.put(JavaFileManager.class, smartFileManager);
+        ResolveWithDeps.preRegister(context);
+        JavaCompilerWithDeps.preRegister(context, this);
+        subTasks = new ArrayList<Future<?>>();
+    }
+
+    /**
+     * Prepare the compiler thread for idleness.
+     */
+    public synchronized void unuse() {
+        assert(inUse);
+        inUse = false;
+        compiler = null;
+        fileManager = null;
+        fileManagerBase = null;
+        smartFileManager = null;
+        context = null;
+        subTasks = null;
+    }
+
+    /**
+     * Expect this key on the next line read from the reader.
+     */
+    private static boolean expect(BufferedReader in, String key) throws IOException {
+        String s = in.readLine();
+        if (s != null && s.equals(key)) {
+            return true;
+        }
+        return false;
+    }
+
+    // The request identifier, for example GENERATE_NEWBYTECODE
+    String id = "";
+
+    public String currentRequestId() {
+        return id;
+    }
+
+    PrintWriter stdout;
+    PrintWriter stderr;
+    int forcedExitCode = 0;
+
+    public void logError(String msg) {
+        stderr.println(msg);
+        forcedExitCode = -1;
+    }
+
+    /**
+     * Invoked by the executor service.
+     */
+    public void run() {
+        // Unique nr that identifies this request.
+        int thisRequest = compilerPool.startRequest();
+        long start = System.currentTimeMillis();
+        int numClasses = 0;
+        StringBuilder compiledPkgs = new StringBuilder();
+        use();
+
+        PrintWriter out = null;
+        try {
+            javacServer.log("<"+thisRequest+"> Connect from "+socket.getRemoteSocketAddress()+" activethreads="+compilerPool.numActiveRequests());
+            BufferedReader in = new BufferedReader(new InputStreamReader(
+                                                       socket.getInputStream()));
+            out = new PrintWriter(new OutputStreamWriter(
+                                                  socket.getOutputStream()));
+            if (!expect(in, JavacServer.PROTOCOL_COOKIE_VERSION)) {
+                javacServer.log("<"+thisRequest+"> Bad protocol from ip "+socket.getRemoteSocketAddress());
+                return;
+            }
+
+            String cookie = in.readLine();
+            if (cookie == null || !cookie.equals(""+javacServer.getCookie())) {
+                javacServer.log("<"+thisRequest+"> Bad cookie from ip "+socket.getRemoteSocketAddress());
+                return;
+            }
+            if (!expect(in, JavacServer.PROTOCOL_CWD)) {
+                return;
+            }
+            String cwd = in.readLine();
+            if (cwd == null)
+                return;
+            if (!expect(in, JavacServer.PROTOCOL_ID)) {
+                return;
+            }
+            id = in.readLine();
+            if (id == null)
+                return;
+            if (!expect(in, JavacServer.PROTOCOL_ARGS)) {
+                return;
+            }
+            ArrayList<String> the_options = new ArrayList<String>();
+            ArrayList<File> the_classes = new ArrayList<File>();
+            Iterable<File> path = Arrays.<File> asList(new File(cwd));
+
+            for (;;) {
+                String l = in.readLine();
+                if (l == null)
+                    return;
+                if (l.equals(JavacServer.PROTOCOL_SOURCES_TO_COMPILE))
+                    break;
+                if (l.startsWith("--server:"))
+                    continue;
+                if (!l.startsWith("-") && l.endsWith(".java")) {
+                    the_classes.add(new File(l));
+                    numClasses++;
+                } else {
+                    the_options.add(l);
+                }
+                continue;
+            }
+
+            // Load sources to compile
+            Set<URI> sourcesToCompile = new HashSet<URI>();
+            for (;;) {
+                String l = in.readLine();
+                if (l == null)
+                    return;
+                if (l.equals(JavacServer.PROTOCOL_VISIBLE_SOURCES))
+                    break;
+                try {
+                    sourcesToCompile.add(new URI(l));
+                    numClasses++;
+                } catch (URISyntaxException e) {
+                    return;
+                }
+            }
+            // Load visible sources
+            Set<URI> visibleSources = new HashSet<URI>();
+            boolean fix_drive_letter_case = System.getProperty("os.name").toLowerCase().equals("windows");
+            for (;;) {
+                String l = in.readLine();
+                if (l == null)
+                    return;
+                if (l.equals(JavacServer.PROTOCOL_END))
+                    break;
+                try {
+                    URI u = new URI(l);
+                    if (fix_drive_letter_case) {
+                        // Make sure the driver letter is lower case.
+                        String s = u.toString();
+                        if (s.startsWith("file:/") &&
+                            Character.isUpperCase(s.charAt(6))) {
+                            u = new URI("file:/"+Character.toLowerCase(s.charAt(6))+s.substring(7));
+                        }
+                    }
+                    visibleSources.add(u);
+                } catch (URISyntaxException e) {
+                    return;
+                }
+            }
+
+            // A completed request has been received.
+
+            // Now setup the actual compilation....
+            // First deal with explicit source files on cmdline and in at file.
+            com.sun.tools.javac.util.ListBuffer<JavaFileObject> compilationUnits =
+                new com.sun.tools.javac.util.ListBuffer<JavaFileObject>();
+            for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(the_classes)) {
+                compilationUnits.append(i);
+            }
+            // Now deal with sources supplied as source_to_compile.
+            com.sun.tools.javac.util.ListBuffer<File> sourcesToCompileFiles =
+                new com.sun.tools.javac.util.ListBuffer<File>();
+            for (URI u : sourcesToCompile) {
+                sourcesToCompileFiles.append(new File(u));
+            }
+            for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
+                compilationUnits.append(i);
+            }
+            // Log the options to be used.
+            StringBuilder options = new StringBuilder();
+            for (String s : the_options) {
+                options.append(">").append(s).append("< ");
+            }
+            javacServer.log(id+" <"+thisRequest+"> options "+options.toString());
+
+            forcedExitCode = 0;
+            // Create a new logger.
+            StringWriter stdoutLog = new StringWriter();
+            StringWriter stderrLog = new StringWriter();
+            stdout = new PrintWriter(stdoutLog);
+            stderr = new PrintWriter(stderrLog);
+            com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+            try {
+                if (compilationUnits.size() > 0) {
+                    // Bind the new logger to the existing context.
+                    context.put(Log.outKey, stderr);
+                    Log.instance(context).setWriter(Log.WriterKind.NOTICE, stdout);
+                    Log.instance(context).setWriter(Log.WriterKind.WARNING, stderr);
+                    Log.instance(context).setWriter(Log.WriterKind.ERROR, stderr);
+                    // Process the options.
+                    com.sun.tools.javac.api.JavacTool.processOptions(context, smartFileManager, the_options);
+                    fileManagerBase.setContext(context);
+                    smartFileManager.setVisibleSources(visibleSources);
+                    smartFileManager.cleanArtifacts();
+                    smartFileManager.setLog(stdout);
+                    Dependencies.instance(context).reset();
+
+                    com.sun.tools.javac.main.Main ccompiler = new com.sun.tools.javac.main.Main("javacTask", stderr);
+                    String[] aa = the_options.toArray(new String[0]);
+
+                    // Do the compilation!
+                    rc = ccompiler.compile(aa, context, compilationUnits.toList(), null);
+
+                    while (numActiveSubTasks()>0) {
+                        try { Thread.sleep(1000); } catch (InterruptedException e) { }
+                    }
+
+                    smartFileManager.flush();
+                }
+            } catch (Exception e) {
+                stderr.println(e.getMessage());
+                forcedExitCode = -1;
+            }
+
+            // Send the response..
+            out.println(JavacServer.PROTOCOL_STDOUT);
+            out.print(stdoutLog);
+            out.println(JavacServer.PROTOCOL_STDERR);
+            out.print(stderrLog);
+            // The compilation is complete! And errors will have already been printed on out!
+            out.println(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS);
+            Map<String,Set<URI>> pa = smartFileManager.getPackageArtifacts();
+            for (String aPkgName : pa.keySet()) {
+                out.println("+"+aPkgName);
+                Set<URI> as = pa.get(aPkgName);
+                for (URI a : as) {
+                    out.println(" "+a.toString());
+                }
+            }
+            Dependencies deps = Dependencies.instance(context);
+            out.println(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES);
+            Map<String,Set<String>> pd = deps.getDependencies();
+            for (String aPkgName : pd.keySet()) {
+                out.println("+"+aPkgName);
+                Set<String> ds = pd.get(aPkgName);
+                    // Everything depends on java.lang
+                    if (!ds.contains(":java.lang")) ds.add(":java.lang");
+                for (String d : ds) {
+                    out.println(" "+d);
+                }
+            }
+            out.println(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS);
+            Map<String,String> pp = deps.getPubapis();
+            for (String aPkgName : pp.keySet()) {
+                out.println("+"+aPkgName);
+                String ps = pp.get(aPkgName);
+                // getPubapis added a space to each line!
+                out.println(ps);
+                compiledPkgs.append(aPkgName+" ");
+            }
+            out.println(JavacServer.PROTOCOL_SYSINFO);
+            out.println("num_cores=" + Runtime.getRuntime().availableProcessors());
+            out.println("max_memory=" + Runtime.getRuntime().maxMemory());
+            out.println(JavacServer.PROTOCOL_RETURN_CODE);
+
+            // Errors from sjavac that affect compilation status!
+            int rcv = rc.exitCode;
+            if (rcv == 0 && forcedExitCode != 0) {
+                rcv = forcedExitCode;
+            }
+            out.println("" + rcv);
+            out.println(JavacServer.PROTOCOL_END);
+            out.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (out != null) out.close();
+                if (!socket.isClosed()) {
+                    socket.close();
+                }
+                socket = null;
+            } catch (Exception e) {
+                javacServer.log("ERROR "+e);
+                e.printStackTrace();
+            }
+            compilerPool.stopRequest();
+            long duration = System.currentTimeMillis()-start;
+            javacServer.addBuildTime(duration);
+            float classpersec = ((float)numClasses)*(((float)1000.0)/((float)duration));
+            javacServer.log(id+" <"+thisRequest+"> "+compiledPkgs+" duration " + duration+ " ms    num_classes="+numClasses+
+                             "     classpersec="+classpersec+" subtasks="+subTasks.size());
+            javacServer.flushLog();
+            unuse();
+            compilerPool.returnCompilerThread(this);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,751 @@
+/*
+ * Copyright (c) 2011-2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Random;
+
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.ProblemException;
+import java.io.*;
+import java.util.*;
+
+/**
+ * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
+ *
+ * <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></p>
+ */
+public class JavacServer {
+    // Responding to this tcp/ip port on localhost.
+
+    private final ServerSocket serverSocket;
+    // The secret cookie shared between server and client through the port file.
+    private final long myCookie;
+    // When the server was started.
+    private long serverStart;
+    // Accumulated build time for all requests, not counting idle time.
+    private long totalBuildTime;
+    // The javac server specific log file.
+    PrintWriter theLog;
+    // The compiler pool that maintains the compiler threads.
+    CompilerPool compilerPool;
+    // For the client, all port files fetched, one per started javac server.
+    // Though usually only one javac server is started by a client.
+    private static Map<String, PortFile> allPortFiles;
+    private static Map<String, Long> maxServerMemory;
+    final static int ERROR_FATAL = -1;
+    final static int ERROR_BUT_TRY_AGAIN = -4712;
+    final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
+    final static String PROTOCOL_CWD = "----THE-CWD----";
+    final static String PROTOCOL_ID = "----THE-ID----";
+    final static String PROTOCOL_ARGS = "----THE-ARGS----";
+    final static String PROTOCOL_SOURCES_TO_COMPILE = "----THE-SOURCES-TO-COMPILE----";
+    final static String PROTOCOL_VISIBLE_SOURCES = "----THE-VISIBLE-SOURCES----";
+    final static String PROTOCOL_END = "----THE-END----";
+    final static String PROTOCOL_STDOUT = "----THE-STDOUT----";
+    final static String PROTOCOL_STDERR = "----THE-STDERR----";
+    final static String PROTOCOL_PACKAGE_ARTIFACTS = "----THE-PACKAGE_ARTIFACTS----";
+    final static String PROTOCOL_PACKAGE_DEPENDENCIES = "----THE-PACKAGE_DEPENDENCIES----";
+    final static String PROTOCOL_PACKAGE_PUBLIC_APIS = "----THE-PACKAGE-PUBLIC-APIS----";
+    final static String PROTOCOL_SYSINFO = "----THE-SYSINFO----";
+    final static String PROTOCOL_RETURN_CODE = "----THE-RETURN-CODE----";
+    // Check if the portfile is gone, every 5 seconds.
+    static int CHECK_PORTFILE_INTERVAL = 5;
+    // Wait 2 seconds for response, before giving up on javac server.
+    static int CONNECTION_TIMEOUT = 2;
+    static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 1;
+    static int MAX_NUM_CONNECT_ATTEMPTS = 3;
+
+    /**
+     * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
+     */
+    private static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
+        if (allPortFiles == null) {
+            allPortFiles = new HashMap<String, PortFile>();
+        }
+        PortFile pf = allPortFiles.get(filename);
+        if (pf == null) {
+            pf = new PortFile(filename);
+            allPortFiles.put(filename, pf);
+        }
+        return pf;
+    }
+
+    /**
+     * Get the cookie used for this server.
+     */
+    long getCookie() {
+        return myCookie;
+    }
+
+    /**
+     * Get the port used for this server.
+     */
+    int getPort() {
+        return serverSocket.getLocalPort();
+    }
+
+    /**
+     * Sum up the total build time for this javac server.
+     */
+    public void addBuildTime(long inc) {
+        totalBuildTime += inc;
+    }
+
+    /**
+     * Log this message.
+     */
+    public void log(String msg) {
+        if (theLog != null) {
+            theLog.println(msg);
+        } else {
+            System.err.println(msg);
+        }
+    }
+
+    /**
+     * Make sure the log is flushed.
+     */
+    public void flushLog() {
+        if (theLog != null) {
+            theLog.flush();
+        }
+    }
+
+    /**
+     * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
+     * is sent as the settings parameter. Returns 0 on success, -1 on failure.
+     */
+    public static int startServer(String settings, PrintStream err) {
+        try {
+            String portfile = Util.extractStringOption("portfile", settings);
+            // The log file collects more javac server specific log information.
+            String logfile = Util.extractStringOption("logfile", settings);
+            // The stdouterr file collects all the System.out and System.err writes to disk.
+            String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+            // We could perhaps use System.setOut and setErr here.
+            // But for the moment we rely on the client to spawn a shell where stdout
+            // and stderr are redirected already.
+            // The pool size is a limit the number of concurrent compiler threads used.
+            // The server might use less than these to avoid memory problems.
+            int poolsize = Util.extractIntOption("poolsize", settings);
+            if (poolsize <= 0) {
+                // If not set, default to the number of cores.
+                poolsize = Runtime.getRuntime().availableProcessors();
+            }
+
+            // How many seconds of inactivity will the server accept before quitting?
+            int keepalive = Util.extractIntOption("keepalive", settings);
+            if (keepalive <= 0) {
+                keepalive = 120;
+            }
+            // The port file is locked and the server port and cookie is written into it.
+            PortFile portFile = getPortFile(portfile);
+            JavacServer s;
+
+            synchronized (portFile) {
+                portFile.lock();
+                portFile.getValues();
+                if (portFile.containsPortInfo()) {
+                    err.println("Javac server not started because portfile exists!");
+                    portFile.unlock();
+                    return -1;
+                }
+                s = new JavacServer(poolsize, logfile);
+                portFile.setValues(s.getPort(), s.getCookie());
+                portFile.unlock();
+            }
+
+            // Run the server. Will delete the port file when shutting down.
+            // It will shut down automatically when no new requests have come in
+            // during the last 125 seconds.
+            s.run(portFile, err, keepalive);
+            // The run loop for the server has exited.
+            return 0;
+        } catch (Exception e) {
+            e.printStackTrace(err);
+            return -1;
+        }
+    }
+
+    /**
+     * Dispatch a compilation request to a javac server.
+     *
+     * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
+     *
+     * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
+     *
+     * @param sources_to_compile The sources to compile.
+     *
+     * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
+     * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
+     *
+     * @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
+     * can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
+     *
+     * The server return meta data about the build in the following parameters.
+     * @param package_artifacts, map from package name to set of created artifacts for that package.
+     * @param package_dependencies, map from package name to set of packages that it depends upon.
+     * @param package_pubapis, map from package name to unique string identifying its pub api.
+     */
+    public static int useServer(String settings, String[] args,
+            Set<URI> sourcesToCompile,
+            Set<URI> visibleSources,
+            Map<URI, Set<String>> visibleClasses,
+            Map<String, Set<URI>> packageArtifacts,
+            Map<String, Set<String>> packageDependencies,
+            Map<String, String> packagePubapis,
+            SysInfo sysinfo,
+            PrintStream out,
+            PrintStream err) {
+        try {
+            // The id can perhaps be used in the future by the javac server to reuse the
+            // JavaCompiler instance for several compiles using the same id.
+            String id = Util.extractStringOption("id", settings);
+            String portfile = Util.extractStringOption("portfile", settings);
+            String logfile = Util.extractStringOption("logfile", settings);
+            String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+            String background = Util.extractStringOption("background", settings);
+            if (background == null || !background.equals("false")) {
+                background = "true";
+            }
+            // The sjavac option specifies how the server part of sjavac is spawned.
+            // If you have the experimental sjavac in your path, you are done. If not, you have
+            // to point to a com.sun.tools.sjavac.Main that supports --startserver
+            // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
+            String sjavac = Util.extractStringOption("sjavac", settings);
+            int poolsize = Util.extractIntOption("poolsize", settings);
+            int keepalive = Util.extractIntOption("keepalive", settings);
+
+            if (keepalive <= 0) {
+                // Default keepalive for server is 120 seconds.
+                // I.e. it will accept 120 seconds of inactivity before quitting.
+                keepalive = 120;
+            }
+            if (portfile == null) {
+                err.println("No portfile was specified!");
+                return -1;
+            }
+            if (logfile == null) {
+                logfile = portfile + ".javaclog";
+            }
+            if (stdouterrfile == null) {
+                stdouterrfile = portfile + ".stdouterr";
+            }
+            // Default to sjavac and hope it is in the path.
+            if (sjavac == null) {
+                sjavac = "sjavac";
+            }
+
+            int attempts = 0;
+            int rc = -1;
+            do {
+                PortFile port_file = getPortFile(portfile);
+                synchronized (port_file) {
+                    port_file.lock();
+                    port_file.getValues();
+                    port_file.unlock();
+                }
+                if (!port_file.containsPortInfo()) {
+                    String cmd = fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, err, stdouterrfile, background);
+
+                    if (background.equals("true") && !port_file.waitForValidValues()) {
+                        // Ouch the server did not start! Lets print its stdouterrfile and the command used.
+                        printFailedAttempt(cmd, stdouterrfile, err);
+                        // And give up.
+                        return -1;
+                    }
+                }
+                rc = connectAndCompile(port_file, id, args, sourcesToCompile, visibleSources,
+                        packageArtifacts, packageDependencies, packagePubapis, sysinfo,
+                        out, err);
+                // Try again until we manage to connect. Any error after that
+                // will cause the compilation to fail.
+                if (rc == ERROR_BUT_TRY_AGAIN) {
+                    // We could not connect to the server. Try again.
+                    attempts++;
+                    try {
+                        Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
+                    } catch (InterruptedException e) {
+                    }
+                }
+            } while (rc == ERROR_BUT_TRY_AGAIN && attempts < MAX_NUM_CONNECT_ATTEMPTS);
+            return rc;
+        } catch (Exception e) {
+            e.printStackTrace(err);
+            return -1;
+        }
+    }
+
+    private static void printFailedAttempt(String cmd, String f, PrintStream err) {
+        err.println("---- Failed to start javac server with this command -----");
+        err.println(cmd);
+        try {
+            BufferedReader in = new BufferedReader(new FileReader(f));
+            err.println("---- stdout/stderr output from attempt to start javac server -----");
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    break;
+                }
+                err.println(l);
+            }
+            err.println("------------------------------------------------------------------");
+        } catch (Exception e) {
+            err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
+        }
+    }
+
+    /**
+     * Spawn the server instance.
+     */
+
+    private JavacServer(int poolSize, String logfile) throws IOException {
+        serverStart = System.currentTimeMillis();
+        // Create a server socket on a random port that is bound to the localhost/127.0.0.1 interface.
+        // I.e only local processes can connect to this port.
+        serverSocket = new ServerSocket(0, 128, InetAddress.getByName(null));
+        compilerPool = new CompilerPool(poolSize, this);
+        Random rnd = new Random();
+        myCookie = rnd.nextLong();
+        theLog = new PrintWriter(logfile);
+        log("Javac server started. port=" + getPort() + " date=" + (new java.util.Date()) + " with poolsize=" + poolSize);
+        flushLog();
+    }
+
+    /**
+     * Fork a background process. Returns the command line used that can be printed if something failed.
+     */
+    private static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
+            final PrintStream err, String stdouterrfile, String background)
+            throws IOException, ProblemException {
+        if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
+            stdouterrfile = null;
+        }
+        final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
+
+        if (background.equals("true")) {
+            sjavac += "%20" + startserver;
+            sjavac = sjavac.replaceAll("%20", " ");
+            sjavac = sjavac.replaceAll("%2C", ",");
+            // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
+            String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
+            if (!(new File("/bin/sh")).canExecute()) {
+                ArrayList<String> wincmd = new ArrayList<String>();
+                wincmd.add("cmd");
+                wincmd.add("/c");
+                wincmd.add("start");
+                wincmd.add("cmd");
+                wincmd.add("/c");
+                wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
+                cmd = wincmd.toArray(new String[wincmd.size()]);
+            }
+            Process pp = null;
+            try {
+                pp = Runtime.getRuntime().exec(cmd);
+            } catch (Exception e) {
+                e.printStackTrace(err);
+                e.printStackTrace(new PrintWriter(stdouterrfile));
+            }
+            StringBuilder rs = new StringBuilder();
+            for (String s : cmd) {
+                rs.append(s + " ");
+            }
+            return rs.toString();
+        }
+
+        // Do not spawn a background server, instead run it within the same JVM.
+        Thread t = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    JavacServer.startServer(startserver, err);
+                } catch (Throwable t) {
+                    t.printStackTrace(err);
+                }
+            }
+        };
+        t.start();
+        return "";
+    }
+
+    /**
+     * Expect this key on the next line read from the reader.
+     */
+    private static boolean expect(BufferedReader in, String key) throws IOException {
+        String s = in.readLine();
+        if (s != null && s.equals(key)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Make a request to the server only to get the maximum possible heap size to use for compilations.
+     *
+     * @param port_file The port file used to synchronize creation of this server.
+     * @param id The identify of the compilation.
+     * @param out Standard out information.
+     * @param err Standard err information.
+     * @return The maximum heap size in bytes.
+     */
+    public static SysInfo connectGetSysInfo(String serverSettings, PrintStream out, PrintStream err) {
+        SysInfo sysinfo = new SysInfo(-1, -1);
+        String id = Util.extractStringOption("id", serverSettings);
+        String portfile = Util.extractStringOption("portfile", serverSettings);
+        try {
+            PortFile pf = getPortFile(portfile);
+            useServer(serverSettings, new String[0],
+                    new HashSet<URI>(),
+                    new HashSet<URI>(),
+                    new HashMap<URI, Set<String>>(),
+                    new HashMap<String, Set<URI>>(),
+                    new HashMap<String, Set<String>>(),
+                    new HashMap<String, String>(),
+                    sysinfo, out, err);
+        } catch (Exception e) {
+            e.printStackTrace(err);
+        }
+        return sysinfo;
+    }
+
+    /**
+     * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
+     * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
+     */
+    private static int connectAndCompile(PortFile portFile, String id, String[] args,
+            Set<URI> sourcesToCompile,
+            Set<URI> visibleSources,
+            Map<String, Set<URI>> packageArtifacts,
+            Map<String, Set<String>> packageDependencies,
+            Map<String, String> packagePublicApis,
+            SysInfo sysinfo,
+            PrintStream out,
+            PrintStream err) {
+        int rc = -3;
+        try {
+            int port = portFile.getPort();
+            if (port == 0) {
+                return ERROR_BUT_TRY_AGAIN;
+            }
+            long cookie = portFile.getCookie();
+
+            // Acquire the localhost/127.0.0.1 address.
+            InetAddress addr = InetAddress.getByName(null);
+            SocketAddress sockaddr = new InetSocketAddress(addr, port);
+            Socket sock = new Socket();
+            int timeoutMs = CONNECTION_TIMEOUT * 1000;
+            try {
+                sock.connect(sockaddr, timeoutMs);
+            } catch (java.net.ConnectException e) {
+                err.println("Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e);
+                return ERROR_BUT_TRY_AGAIN;
+            }
+            if (!sock.isConnected()) {
+                err.println("Could not connect to javac server found in portfile: " + portFile.getFilename());
+                return ERROR_BUT_TRY_AGAIN;
+            }
+            BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+            PrintWriter sockout = new PrintWriter(sock.getOutputStream());
+
+            sockout.println(PROTOCOL_COOKIE_VERSION);
+            sockout.println("" + cookie);
+            sockout.println(PROTOCOL_CWD);
+            sockout.println(System.getProperty("user.dir"));
+            sockout.println(PROTOCOL_ID);
+            sockout.println(id);
+            sockout.println(PROTOCOL_ARGS);
+            for (String s : args) {
+                StringBuffer buf = new StringBuffer();
+                String[] paths = s.split(File.pathSeparator);
+                int c = 0;
+                for (String path : paths) {
+                    File f = new File(path);
+                    if (f.isFile() || f.isDirectory()) {
+                        buf.append(f.getAbsolutePath());
+                        c++;
+                        if (c < paths.length) {
+                            buf.append(File.pathSeparator);
+                        }
+                    } else {
+                        buf = new StringBuffer(s);
+                        break;
+                    }
+                }
+                sockout.println(buf.toString());
+            }
+            sockout.println(PROTOCOL_SOURCES_TO_COMPILE);
+            for (URI uri : sourcesToCompile) {
+                sockout.println(uri.toString());
+            }
+            sockout.println(PROTOCOL_VISIBLE_SOURCES);
+            for (URI uri : visibleSources) {
+                sockout.println(uri.toString());
+            }
+            sockout.println(PROTOCOL_END);
+            sockout.flush();
+
+            StringBuffer stdout = new StringBuffer();
+            StringBuffer stderr = new StringBuffer();
+
+            if (!expect(in, PROTOCOL_STDOUT)) {
+                return ERROR_FATAL;
+            }
+            // Load stdout
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    return ERROR_FATAL;
+                }
+                if (l.equals(PROTOCOL_STDERR)) {
+                    break;
+                }
+                stdout.append(l);
+                stdout.append('\n');
+            }
+            // Load stderr
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    return ERROR_FATAL;
+                }
+                if (l.equals(PROTOCOL_PACKAGE_ARTIFACTS)) {
+                    break;
+                }
+                stderr.append(l);
+                stderr.append('\n');
+            }
+            // Load the package artifacts
+            Set<URI> lastUriSet = null;
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    return ERROR_FATAL;
+                }
+                if (l.equals(PROTOCOL_PACKAGE_DEPENDENCIES)) {
+                    break;
+                }
+                if (l.length() > 1 && l.charAt(0) == '+') {
+                    String pkg = l.substring(1);
+                    lastUriSet = new HashSet<URI>();
+                    packageArtifacts.put(pkg, lastUriSet);
+                } else if (l.length() > 1 && lastUriSet != null) {
+                    lastUriSet.add(new URI(l.substring(1)));
+                }
+            }
+            // Load package dependencies
+            Set<String> lastPackageSet = null;
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    return ERROR_FATAL;
+                }
+                if (l.equals(PROTOCOL_PACKAGE_PUBLIC_APIS)) {
+                    break;
+                }
+                if (l.length() > 1 && l.charAt(0) == '+') {
+                    String pkg = l.substring(1);
+                    lastPackageSet = new HashSet<String>();
+                    packageDependencies.put(pkg, lastPackageSet);
+                } else if (l.length() > 1 && lastPackageSet != null) {
+                    lastPackageSet.add(l.substring(1));
+                }
+            }
+            // Load package pubapis
+            Map<String, StringBuffer> tmp = new HashMap<String, StringBuffer>();
+            StringBuffer lastPublicApi = null;
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    return ERROR_FATAL;
+                }
+                if (l.equals(PROTOCOL_SYSINFO)) {
+                    break;
+                }
+                if (l.length() > 1 && l.charAt(0) == '+') {
+                    String pkg = l.substring(1);
+                    lastPublicApi = new StringBuffer();
+                    tmp.put(pkg, lastPublicApi);
+                } else if (l.length() > 1 && lastPublicApi != null) {
+                    lastPublicApi.append(l.substring(1));
+                    lastPublicApi.append("\n");
+                }
+            }
+            for (String p : tmp.keySet()) {
+                assert (packagePublicApis.get(p) == null);
+                String api = tmp.get(p).toString();
+                packagePublicApis.put(p, api);
+            }
+            // Now reading the max memory possible.
+            for (;;) {
+                String l = in.readLine();
+                if (l == null) {
+                    return ERROR_FATAL;
+                }
+                if (l.equals(PROTOCOL_RETURN_CODE)) {
+                    break;
+                }
+                if (l.startsWith("num_cores=") && sysinfo != null) {
+                    sysinfo.numCores = Integer.parseInt(l.substring(10));
+                }
+                if (l.startsWith("max_memory=") && sysinfo != null) {
+                    sysinfo.maxMemory = Long.parseLong(l.substring(11));
+                }
+            }
+            String l = in.readLine();
+            if (l == null) {
+                err.println("No return value from the server!");
+                return ERROR_FATAL;
+            }
+            rc = Integer.parseInt(l);
+            out.print(stdout);
+            err.print(stderr);
+        } catch (Exception e) {
+            e.printStackTrace(err);
+        }
+        return rc;
+    }
+
+    /**
+     * Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
+     * javac server.
+     */
+    private void run(PortFile portFile, PrintStream err, int keepalive) {
+        boolean fileDeleted = false;
+        long timeSinceLastCompile;
+        try {
+            // Every 5 second (check_portfile_interval) we test if the portfile has disappeared => quit
+            // Or if the last request was finished more than 125 seconds ago => quit
+            // 125 = seconds_of_inactivity_before_shutdown+check_portfile_interval
+            serverSocket.setSoTimeout(CHECK_PORTFILE_INTERVAL*1000);
+            for (;;) {
+                try {
+                    Socket s = serverSocket.accept();
+                    CompilerThread ct = compilerPool.grabCompilerThread();
+                    ct.setSocket(s);
+                    compilerPool.execute(ct);
+                    flushLog();
+                } catch (java.net.SocketTimeoutException e) {
+                    if (compilerPool.numActiveRequests() > 0) {
+                        // Never quit while there are active requests!
+                        continue;
+                    }
+                    // If this is the timeout after the portfile
+                    // has been deleted by us. Then we truly stop.
+                    if (fileDeleted) {
+                        log("Quitting because of "+(keepalive+CHECK_PORTFILE_INTERVAL)+" seconds of inactivity!");
+                        break;
+                    }
+                    // Check if the portfile is still there.
+                    if (!portFile.exists()) {
+                        // Time to quit because the portfile was deleted by another
+                        // process, probably by the makefile that is done building.
+                        log("Quitting because portfile was deleted!");
+                        flushLog();
+                        break;
+                    }
+                    // Check if portfile.stop is still there.
+                    if (portFile.markedForStop()) {
+                        // Time to quit because another process touched the file
+                        // server.port.stop to signal that the server should stop.
+                        // This is necessary on some operating systems that lock
+                        // the port file hard!
+                        log("Quitting because a portfile.stop file was found!");
+                        portFile.delete();
+                        flushLog();
+                        break;
+                    }
+                    // Does the portfile still point to me?
+                    if (!portFile.stillMyValues()) {
+                        // Time to quit because another build has started.
+                        log("Quitting because portfile is now owned by another javac server!");
+                        flushLog();
+                        break;
+                    }
+
+                    // Check how long since the last request finished.
+                    long diff = System.currentTimeMillis() - compilerPool.lastRequestFinished();
+                    if (diff < keepalive * 1000) {
+                        // Do not quit if we have waited less than 120 seconds.
+                        continue;
+                    }
+                    // Ok, time to quit because of inactivity. Perhaps the build
+                    // was killed and the portfile not cleaned up properly.
+                    portFile.delete();
+                    fileDeleted = true;
+                    log("" + keepalive + " seconds of inactivity quitting in "
+                        + CHECK_PORTFILE_INTERVAL + " seconds!");
+                    flushLog();
+                    // Now we have a second 5 second grace
+                    // period where javac remote requests
+                    // that have loaded the data from the
+                    // recently deleted portfile can connect
+                    // and complete their requests.
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace(err);
+            e.printStackTrace(theLog);
+            flushLog();
+        } finally {
+            compilerPool.shutdown();
+        }
+        long realTime = System.currentTimeMillis() - serverStart;
+        log("Shutting down.");
+        log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
+        flushLog();
+    }
+
+    public static void cleanup(String... args) {
+        String settings = Util.findServerSettings(args);
+        if (settings == null) return;
+        String portfile = Util.extractStringOption("portfile", settings);
+        String background = Util.extractStringOption("background", settings);
+        if (background != null && background.equals("false")) {
+            // If the server runs within this jvm, then delete the portfile,
+            // since this jvm is about to exit soon.
+            File f = new File(portfile);
+            f.delete();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.FileLockInterruptionException;
+import com.sun.tools.sjavac.Log;
+
+/**
+ * The PortFile class mediates access to a short binary file containing the tcp/ip port (for the localhost)
+ * and a cookie necessary for the server answering on that port. The file can be locked using file system
+ * primitives to avoid race conditions when several javac clients are started at the same. Note that file
+ * system locking is not always supported on a all operating systems and/or file systems.
+ *
+ * <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></p>
+ */
+class PortFile {
+
+    // Port file format:
+    // byte ordering: high byte first = big endian
+    // Magic nr, 4 byte int, first in file.
+    private final static int magicNr = 0x1174;
+    // Followed by a 4 byte int, with the port nr.
+    // Followed by a 8 byte long, with cookie nr.
+
+    private String filename;
+    private File file;
+    private File stopFile;
+    private RandomAccessFile rwfile;
+    private FileChannel channel;
+    private FileLock lock;
+
+    private boolean containsPortInfo;
+    private int serverPort;
+    private long serverCookie;
+    private int myServerPort;
+    private long myServerCookie;
+
+    /**
+     * Create a new portfile.
+     * @param filename is the path to the file.
+     */
+    public PortFile(String fn) throws FileNotFoundException
+    {
+        filename = fn;
+        file = new File(filename);
+        stopFile = new File(filename+".stop");
+        rwfile = new RandomAccessFile(file, "rw");
+        // The rwfile should only be readable by the owner of the process
+        // and no other! How do we do that on a RandomAccessFile?
+        channel = rwfile.getChannel();
+        containsPortInfo = false;
+        lock = null;
+    }
+
+    /**
+     * Lock the port file.
+     */
+    void lock() throws IOException {
+        lock = channel.lock();
+    }
+
+    /**
+     * Read the values from the port file in the file system.
+     * Expects the port file to be locked.
+     */
+    public void getValues()  {
+        containsPortInfo = false;
+        if (lock == null) {
+            // Not locked, remain ignorant about port file contents.
+            return;
+        }
+        try {
+            if (rwfile.length()>0) {
+                rwfile.seek(0);
+                int nr = rwfile.readInt();
+                serverPort = rwfile.readInt();
+                serverCookie = rwfile.readLong();
+
+                if (nr == magicNr) {
+                    containsPortInfo = true;
+                } else {
+                    containsPortInfo = false;
+                }
+            }
+        } catch (Exception e) {
+            containsPortInfo = false;
+        }
+    }
+
+    /**
+     * Did the locking and getValues succeed?
+     */
+    public boolean containsPortInfo() {
+        return containsPortInfo;
+    }
+
+    /**
+     * If so, then we can acquire the tcp/ip port on localhost.
+     */
+    public int getPort() {
+        assert(containsPortInfo);
+        return serverPort;
+    }
+
+    /**
+     * If so, then we can acquire the server cookie.
+     */
+    public long getCookie() {
+        assert(containsPortInfo);
+        return serverCookie;
+    }
+
+    /**
+     * Store the values into the locked port file.
+     */
+    public void setValues(int port, long cookie) throws IOException {
+        assert(lock != null);
+        rwfile.seek(0);
+        // Write the magic nr that identifes a port file.
+        rwfile.writeInt(magicNr);
+        rwfile.writeInt(port);
+        rwfile.writeLong(cookie);
+        myServerPort = port;
+        myServerCookie = cookie;
+    }
+
+    /**
+     * Delete the port file.
+     */
+    public void delete() throws IOException {
+        // Access to file must be closed before deleting.
+        rwfile.close();
+        // Now delete.
+        file.delete();
+    }
+
+    /**
+     * Is the port file still there?
+     */
+    public boolean exists() throws IOException {
+        return file.exists();
+    }
+
+    /**
+     * Is a stop file there?
+     */
+    public boolean markedForStop() throws IOException {
+        if (stopFile.exists()) {
+            try {
+                stopFile.delete();
+            } catch (Exception e)
+            {}
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Unlock the port file.
+     */
+    public void unlock() throws IOException {
+        assert(lock != null);
+        lock.release();
+        lock = null;
+    }
+
+    /**
+     * Wait for the port file to contain values that look valid.
+     * Return true, if a-ok, false if the valid values did not materialize within 5 seconds.
+     */
+    public synchronized boolean waitForValidValues() throws IOException, FileNotFoundException {
+        for (int tries = 0; tries < 50; tries++) {
+            lock();
+            getValues();
+            unlock();
+            if (containsPortInfo) {
+                Log.debug("Found valid values in port file after waiting "+(tries*100)+"ms");
+                return true;
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e)
+            {}
+        }
+        Log.debug("Gave up waiting for valid values in port file");
+        return false;
+    }
+
+    /**
+     * Check if the portfile still contains my values, assuming that I am the server.
+     */
+    public synchronized boolean stillMyValues() throws IOException, FileNotFoundException {
+        for (;;) {
+            try {
+                lock();
+                getValues();
+                unlock();
+                if (containsPortInfo) {
+                    if (serverPort == myServerPort &&
+                        serverCookie == myServerCookie) {
+                        // Everything is ok.
+                        return true;
+                    }
+                    // Someone has overwritten the port file.
+                    // Probably another javac server, lets quit.
+                    return false;
+                }
+                // Something else is wrong with the portfile. Lets quit.
+                return false;
+            } catch (FileLockInterruptionException e) {
+                continue;
+            }
+            catch (ClosedChannelException e) {
+                // The channel has been closed since sjavac is exiting.
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Return the name of the port file.
+     */
+    public String getFilename() {
+        return filename;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/SysInfo.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.
+ */
+
+/**
+ * A utility class used to report information about the system
+ * where the javac server is running.
+ *
+ * <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></p>
+ */
+package com.sun.tools.sjavac.server;
+
+public class SysInfo {
+    public int numCores;
+    public long maxMemory;
+
+    public SysInfo(int nc, long mm) {
+        numCores = nc;
+        maxMemory = mm;
+    }
+}
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -149,6 +149,56 @@
     <A extends Annotation> A getAnnotation(Class<A> annotationType);
 
     /**
+     * Returns an array of all of this element's annotation for the
+     * specified type if such annotations are present, else an empty
+     * array.  The annotation may be either inherited or directly
+     * present on this element. This method will look through a container
+     * annotation (if present) if the supplied annotation type is
+     * repeatable.
+     *
+     * <p> The annotations returned by this method could contain an element
+     * whose value is of type {@code Class}.
+     * This value cannot be returned directly:  information necessary to
+     * locate and load a class (such as the class loader to use) is
+     * not available, and the class might not be loadable at all.
+     * Attempting to read a {@code Class} object by invoking the relevant
+     * method on the returned annotation
+     * will result in a {@link MirroredTypeException},
+     * from which the corresponding {@link TypeMirror} may be extracted.
+     * Similarly, attempting to read a {@code Class[]}-valued element
+     * will result in a {@link MirroredTypesException}.
+     *
+     * <blockquote>
+     * <i>Note:</i> This method is unlike others in this and related
+     * interfaces.  It operates on runtime reflective information &mdash;
+     * representations of annotation types currently loaded into the
+     * VM &mdash; rather than on the representations defined by and used
+     * throughout these interfaces.  Consequently, calling methods on
+     * the returned annotation object can throw many of the exceptions
+     * that can be thrown when calling methods on an annotation object
+     * returned by core reflection.  This method is intended for
+     * callers that are written to operate on a known, fixed set of
+     * annotation types.
+     * </blockquote>
+     *
+     * @param <A>  the annotation type
+     * @param annotationType  the {@code Class} object corresponding to
+     *          the annotation type
+     * @return this element's annotations for the specified annotation
+     *         type if present on this element, else an empty array
+     *
+     * @see #getAnnotationMirrors()
+     * @see #getAnnotation(java.lang.Class)
+     * @see java.lang.reflect.AnnotatedElement#getAnnotations
+     * @see EnumConstantNotPresentException
+     * @see AnnotationTypeMismatchException
+     * @see IncompleteAnnotationException
+     * @see MirroredTypeException
+     * @see MirroredTypesException
+     */
+    <A extends Annotation> A[] getAnnotations(Class<A> annotationType);
+
+    /**
      * Returns the modifiers of this element, excluding annotations.
      * Implicit modifiers, such as the {@code public} and {@code static}
      * modifiers of interface members, are included.
--- a/langtools/test/com/sun/javadoc/5093723/T5093723.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java	Sun Jan 20 23:39:11 2013 -0800
@@ -36,7 +36,7 @@
     private static final String BUG_ID = "5093723";
 
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID + ".out", "-source", "5",
+        "-d", BUG_ID + ".out", "-source", "5", "-Xdoclint:none",
         SRC_DIR + "/DocumentedClass.java",
         SRC_DIR + "/UndocumentedClass.java"
     };
--- a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,7 @@
         String srcdir = System.getProperty("test.src", ".");
 
         runJavadoc(new String[] {"-d", TMPDIR_STRING1,
+                                 "-Xdoclint:none",
                                  "-overview", (srcdir + FS + "overview.html"),
                                  "-header", "<A HREF=\"{@docroot}/package-list\">{&#064;docroot}</A> <A HREF=\"{@docRoot}/help-doc\">{&#064;docRoot}</A>",
                                  "-sourcepath", srcdir,
--- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
 
     //Javadoc arguments.
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, SRC_DIR + FS + "C2.java"
+        "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C2.java"
     };
 
     //Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -222,19 +222,19 @@
 
     private static final String[] ARGS1 =
         new String[] {
-            "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
+            "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
 
     private static final String[] ARGS2 =
         new String[] {
-            "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
+            "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
 
     private static final String[] ARGS3 =
         new String[] {
-            "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+            "-Xdoclint:none", "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
 
     private static final String[] ARGS4 =
         new String[] {
-            "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+            "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
 
     /**
      * The entry point of the test.
--- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
 
     //Javadoc arguments.
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2"
+        "-Xdoclint:none", "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2"
     };
 
     //Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,6 @@
  * @author Bhavesh Patel
  */
 @Documented
-@ContainedBy(ContainerSynthDoc.class)
+@Repeatable(ContainerSynthDoc.class)
 public @interface ContaineeSynthDoc {
 }
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
  * @author Bhavesh Patel
  */
 @Documented
-@ContainerFor(ContaineeSynthDoc.class)
 public @interface ContainerSynthDoc {
 
     ContaineeSynthDoc[] value();
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,6 @@
  * @author Bhavesh Patel
  */
 @Documented
-@ContainedBy(ContainerSynthNotDoc.class)
+@Repeatable(ContainerSynthNotDoc.class)
 public @interface ContaineeSynthDoc {
 }
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
  *
  * @author Bhavesh Patel
  */
-@ContainerFor(ContaineeSynthDoc.class)
 public @interface ContainerSynthNotDoc {
 
     ContaineeSynthDoc[] value();
--- a/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
 
     //Javadoc arguments.
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java"
+        "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java"
     };
 
     //Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
 
     private static final String BUG_ID = "4496223-4496270-4618686-4720974-4812240-6253614-6253604";
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
+        "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
     };
 
     /**
--- a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
     };
     private static final String[][] NEGATED_TEST = NO_TEST;
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java"
+        "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java"
     };
 
     /**
--- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
     //Javadoc arguments.
     private static final String[] ARGS =
         new String[] {
+            "-Xdoclint:none",
             "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag",
             "todo", "pkg1", "pkg2"
         };
--- a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
     };
     private static final String[][] NEGATED_TEST = NO_TEST;
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, SRC_DIR + FS + "C.java"
+        "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C.java"
     };
 
     /**
--- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,11 +43,11 @@
 
     //Javadoc arguments.
     private static final String[] ARGS = new String[] {
-        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+        "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
     };
 
     private static final String[] ARGS2 = new String[] {
-        "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
+        "-Xdoclint:none", "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
     };
 
     //Input for string search tests.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AnchorTest.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,93 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8004832
+ * @summary Add new doclint package
+ * @build DocLintTester
+ * @run main DocLintTester -ref AnchorTest.out AnchorTest.java
+ */
+
+/** */
+public class AnchorTest {
+    // tests for <a name=value>
+
+    /**
+     * <a name=foo></a>
+     */
+    public void a_name_foo() { }
+
+    /**
+     * <a name=foo></a>
+     */
+    public void a_name_already_defined() { }
+
+    /**
+     * <a name=></a>
+     */
+    public void a_name_empty() { }
+
+    /**
+     * <a name=123 ></a>
+     */
+    public void a_name_invalid() { }
+
+    /**
+     * <a name ></a>
+     */
+    public void a_name_missing() { }
+
+    // tests for <a id=value>
+
+    /**
+     * <a id=a_id_foo></a>
+     */
+    public void a_id_foo() { }
+
+    /**
+     * <a id=foo></a>
+     */
+    public void a_id_already_defined() { }
+
+    /**
+     * <a id=></a>
+     */
+    public void a_id_empty() { }
+
+    /**
+     * <a id=123 ></a>
+     */
+    public void a_id_invalid() { }
+
+    /**
+     * <a id ></a>
+     */
+    public void a_id_missing() { }
+
+    // tests for id=value on non-<a> tags
+
+    /**
+     * <p id=p_id_foo>text</p>
+     */
+    public void p_id_foo() { }
+
+    /**
+     * <p id=foo>text</p>
+     */
+    public void p_id_already_defined() { }
+
+    /**
+     * <p id=>text</p>
+     */
+    public void p_id_empty() { }
+
+    /**
+     * <p id=123 >text</p>
+     */
+    public void p_id_invalid() { }
+
+    /**
+     * <p id >text</p>
+     */
+    public void p_id_missing() { }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AnchorTest.out	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,37 @@
+AnchorTest.java:19: error: anchor already defined: foo
+     * <a name=foo></a>
+          ^
+AnchorTest.java:24: error: invalid name for anchor: ""
+     * <a name=></a>
+          ^
+AnchorTest.java:29: error: invalid name for anchor: "123"
+     * <a name=123 ></a>
+          ^
+AnchorTest.java:34: error: no value given for anchor
+     * <a name ></a>
+          ^
+AnchorTest.java:46: error: anchor already defined: foo
+     * <a id=foo></a>
+          ^
+AnchorTest.java:51: error: invalid name for anchor: ""
+     * <a id=></a>
+          ^
+AnchorTest.java:56: error: invalid name for anchor: "123"
+     * <a id=123 ></a>
+          ^
+AnchorTest.java:61: error: no value given for anchor
+     * <a id ></a>
+          ^
+AnchorTest.java:73: error: anchor already defined: foo
+     * <p id=foo>text</p>
+          ^
+AnchorTest.java:78: error: invalid name for anchor: ""
+     * <p id=>text</p>
+          ^
+AnchorTest.java:83: error: invalid name for anchor: "123"
+     * <p id=123 >text</p>
+          ^
+AnchorTest.java:88: error: no value given for anchor
+     * <p id >text</p>
+          ^
+12 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndTagsTest.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006236
+ * @summary doclint: structural issue hidden
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html EndTagsTest.java
+ * @run main DocLintTester -ref EndTagsTest.out EndTagsTest.java
+ */
+
+/** */
+public class EndTagsTest {
+    /** <p>  <a name="a1"> text <img alt="image" src="image.png"> </a> </p> */
+    public void valid_all() { }
+
+    /** <p>  <a name="a2"> text <img alt="image" src="image.png"> </a> */
+    public void valid_omit_optional_close() { }
+
+    /** </a> */
+    public void invalid_missing_start() { }
+
+    /** <p> </a> */
+    public void invalid_missing_start_2() { }
+
+    /** <p> text </p> </a> */
+    public void invalid_missing_start_3() { }
+
+    /** <img alt="image" src="image.png"> </img> */
+    public void invalid_end() { }
+
+    /** <invalid> </invalid> */
+    public void unknown_start_end() { }
+
+    /** <invalid> */
+    public void unknown_start() { }
+
+    /** </invalid> */
+    public void unknown_end() { }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndTagsTest.out	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,25 @@
+EndTagsTest.java:18: error: unexpected end tag: </a>
+    /** </a> */
+        ^
+EndTagsTest.java:21: error: unexpected end tag: </a>
+    /** <p> </a> */
+            ^
+EndTagsTest.java:24: error: unexpected end tag: </a>
+    /** <p> text </p> </a> */
+                      ^
+EndTagsTest.java:27: error: invalid end tag: </img>
+    /** <img alt="image" src="image.png"> </img> */
+                                          ^
+EndTagsTest.java:30: error: unknown tag: invalid
+    /** <invalid> </invalid> */
+        ^
+EndTagsTest.java:30: error: unknown tag: invalid
+    /** <invalid> </invalid> */
+                  ^
+EndTagsTest.java:33: error: unknown tag: invalid
+    /** <invalid> */
+        ^
+EndTagsTest.java:36: error: unknown tag: invalid
+    /** </invalid> */
+        ^
+8 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/LiteralTest.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006228
+ * @summary Doclint doesn't detect <code> {@code nested inline} </code>
+ * @build DocLintTester
+ * @run main DocLintTester -ref LiteralTest.out LiteralTest.java
+ */
+
+/** */
+public class LiteralTest {
+    /** <code> abc {@literal < & > } def </code> */
+    public void ok_literal_in_code() { }
+
+    /** <code> abc {@code < & > } def </code> */
+    public void bad_code_in_code() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/LiteralTest.out	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,4 @@
+LiteralTest.java:14: warning: {@code} within <code>
+    /** <code> abc {@code < & > } def </code> */
+                   ^
+1 warning
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,11 +6,9 @@
  * @compile/fail/ref=BaseAnnoAsContainerAnno.out -XDrawDiagnostics BaseAnnoAsContainerAnno.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(Foo.class)
-@ContainerFor(Foo.class)
+@Repeatable(Foo.class)
 @interface Foo {
     Foo[] value() default {};
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-BaseAnnoAsContainerAnno.java:15:11: compiler.err.cyclic.annotation.element
+BaseAnnoAsContainerAnno.java:13:11: compiler.err.cyclic.annotation.element
 1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,9 @@
 import java.lang.annotation.*;
 
 @Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @Retention(RetentionPolicy.RUNTIME)
 @interface Foos {
     Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,32 +32,29 @@
 
 import java.lang.annotation.*;
 
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @Target(ElementType.TYPE)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @Target(ElementType.ANNOTATION_TYPE)
 @interface Foos {
     Foo[] value();
 }
 
-@ContainedBy(Bars.class)
+@Repeatable(Bars.class)
 @Target(ElementType.TYPE)
 @interface Bar {}
 
-@ContainerFor(Bar.class)
 @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
 @interface Bars {
     Bar[] value();
 }
 
 
-@ContainedBy(Bazs.class)
+@Repeatable(Bazs.class)
 @Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
 @interface Baz {}
 
-@ContainerFor(Baz.class)
 @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
 @interface Bazs {
     Baz[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,17 +30,15 @@
  * @compile ClassReaderDefault.java
  * @compile SeparateCompile.java
  */
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
 public class ClassReaderDefault {
 }
 
-@ContainerFor(Foo.class)
 @interface FooContainer {
      Foo[] value();
      int f() default 0;
 }
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,15 +30,13 @@
  * @run compile ContainerHasRepeatedContained.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
 @interface Bar {}
 
 @Bar
 @Bar
-@ContainerFor(Bar.class)
 @interface BarContainer {
     Bar[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,17 +6,14 @@
  * @compile/fail/ref=CyclicAnnotation.out -XDrawDiagnostics CyclicAnnotation.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(Foo.class)
-@ContainerFor(Baz.class)
+@Repeatable(Foo.class)
 @interface Baz {
     Foo[] value() default {};
 }
 
-@ContainedBy(Baz.class)
-@ContainerFor(Foo.class)
+@Repeatable(Baz.class)
 @interface Foo{
     Baz[] value() default {};
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,6 +1,2 @@
-CyclicAnnotation.java:12:1: compiler.err.invalid.container.wrong.containerfor: Foo, Baz
-CyclicAnnotation.java:13:1: compiler.err.invalid.container.wrong.containedby: Foo, Baz
-CyclicAnnotation.java:15:11: compiler.err.cyclic.annotation.element
-CyclicAnnotation.java:18:1: compiler.err.invalid.container.wrong.containerfor: Baz, Foo
-CyclicAnnotation.java:19:1: compiler.err.invalid.container.wrong.containedby: Baz, Foo
-5 errors
+CyclicAnnotation.java:13:11: compiler.err.cyclic.annotation.element
+1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,13 +29,11 @@
  * @compile DefaultCasePresent.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer {
     Foo[] value();
     String other() default "other-method";
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,12 +39,11 @@
 
 @Bar("katt")
 @Bar("lol")
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
 @interface Bar {
     String value();
 }
 
-@ContainerFor(Bar.class)
 @interface BarContainer {
     Bar[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,15 +6,13 @@
  * @compile/fail/ref=DocumentedContainerAnno.out -XDrawDiagnostics DocumentedContainerAnno.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 import java.lang.annotation.Documented;
 
 @Documented
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer{
     Foo[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-DocumentedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.documented: FooContainer, Foo
+DocumentedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.documented: FooContainer, Foo
 1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,15 +6,13 @@
  * @compile/fail/ref=InheritedContainerAnno.out -XDrawDiagnostics InheritedContainerAnno.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 import java.lang.annotation.Inherited;
 
 @Inherited
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer{
     Foo[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-InheritedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.inherited: FooContainer, Foo
+InheritedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.inherited: FooContainer, Foo
 1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,11 +32,10 @@
 
 import java.lang.annotation.*;
 
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @Target(ElementType.ANNOTATION_TYPE)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @Target(ElementType.TYPE)
 @interface Foos {
     Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail MissingContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-
-@ContainerFor(MissingContainedBy.class)
-@interface Foos {
-    MissingContainedBy[] value();
-}
-
-public @interface MissingContainedBy {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
  * @compile/fail/ref=MissingContainer.out -XDrawDiagnostics MissingContainer.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy()
+@Repeatable()
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer {
     Foo[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,4 @@
-MissingContainer.java:20:1: compiler.err.invalid.containedby.annotation: Foo
-MissingContainer.java:20:6: compiler.err.invalid.containedby.annotation: Foo
-MissingContainer.java:12:1: compiler.err.annotation.missing.default.value: java.lang.annotation.ContainedBy, value
-MissingContainer.java:15:1: compiler.err.invalid.container.wrong.containedby: Foo, FooContainer
-4 errors
+MissingContainer.java:18:1: compiler.err.invalid.repeatable.annotation: Foo
+MissingContainer.java:18:6: compiler.err.invalid.repeatable.annotation: Foo
+MissingContainer.java:11:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Repeatable, value
+3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail MissingContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@interface Foos {
-    MissingContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface MissingContainerFor {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
  * @compile/fail/ref=MissingDefaultCase1.out -XDrawDiagnostics MissingDefaultCase1.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer {
     Foo[] value();
     String other();  // missing default clause
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-MissingDefaultCase1.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
-MissingDefaultCase1.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other()
+MissingDefaultCase1.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
+MissingDefaultCase1.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other()
 2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
  * @compile/fail/ref=MissingDefaultCase2.out -XDrawDiagnostics MissingDefaultCase2.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer {
     Foo[] value();
     Foo other();  // missing default clause and return type is an annotation
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-MissingDefaultCase2.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
-MissingDefaultCase2.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other()
+MissingDefaultCase2.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
+MissingDefaultCase2.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other()
 2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
  * @compile/fail/ref=MissingValueMethod.out -XDrawDiagnostics MissingValueMethod.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface FooContainer{
     Foo[] values();  // wrong method name
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,4 +1,4 @@
-MissingValueMethod.java:20:1: compiler.err.invalid.containedby.annotation.no.value: FooContainer
-MissingValueMethod.java:20:6: compiler.err.invalid.containedby.annotation.no.value: FooContainer
-MissingValueMethod.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, values()
+MissingValueMethod.java:18:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
+MissingValueMethod.java:18:6: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
+MissingValueMethod.java:11:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
 3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,19 +29,16 @@
  * @compile MultiLevelRepeatableAnno.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {}
 
-@ContainedBy(FooContainerContainer.class)
-@ContainerFor(Foo.class)
+@Repeatable(FooContainerContainer.class)
 @interface FooContainer {
     Foo[] value();
 }
 
-@ContainerFor(FooContainer.class)
 @interface FooContainerContainer {
   FooContainer[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,25 +29,22 @@
  * @compile MultipleAnnoMixedOrder.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {
     int getNumbers();
 }
 
-@ContainerFor(Foo.class)
 @interface FooContainer {
   Foo[] value();
 }
 
-@ContainedBy(BazContainer.class)
+@Repeatable(BazContainer.class)
 @interface Baz {
     String getStr();
 }
 
-@ContainerFor(Baz.class)
 @interface BazContainer {
   Baz[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,17 +34,15 @@
 import java.lang.annotation.*;
 
 @Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @interface Foo {}
 
 @Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(FoosFoos.class)
-@ContainerFor(Foo.class)
+@Repeatable(FoosFoos.class)
 @interface Foos {
     Foo[] value();
 }
 
-@ContainerFor(Foos.class)
 @Retention(RetentionPolicy.RUNTIME)
 @interface FoosFoos {
     Foos[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy
-NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy
+NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable
+NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable
 2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,20 +30,18 @@
  * @run compile RepMemberAnno.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
 public class RepMemberAnno {
     @Bar("Apa") @Bar("Banan")
     public void meh() {}
 }
 
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
 @interface Bar {
     String value();
 }
 
-@ContainerFor(Bar.class)
 @interface BarContainer {
     Bar[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,21 +34,19 @@
 
 
 @Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
 public @interface RepSelfMemberAnno {
     @RepSelfMemberAnno @RepSelfMemberAnno
     String meh() default "banan";
 }
 
 
-@ContainedBy(BarContainerContainer.class)
+@Repeatable(BarContainerContainer.class)
 @Retention(RetentionPolicy.RUNTIME)
-@ContainerFor(RepSelfMemberAnno.class)
 @interface BarContainer {
     RepSelfMemberAnno[] value();
 }
 
-@ContainerFor(BarContainer.class)
 @Retention(RetentionPolicy.RUNTIME)
 @interface BarContainerContainer {
     BarContainer[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 
 import java.lang.annotation.*;
 
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @interface Foo {}
 
 @interface Foos {
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,9 @@
 
 import java.lang.annotation.*;
 
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @Target(ElementType.ANNOTATION_TYPE)
 @interface Foos {
     Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-RepeatingTargetNotAllowed.java:44:5: compiler.err.invalid.containedby.annotation.incompatible.target: Foos, Foo
+RepeatingTargetNotAllowed.java:43:5: compiler.err.invalid.repeatable.annotation.incompatible.target: Foos, Foo
 1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
 
 import java.lang.annotation.*;
 
-@ContainerFor(SelfRepeatingAnno.class)
 @Retention(RetentionPolicy.RUNTIME)
 @interface Foos {
     SelfRepeatingAnno[] value();
@@ -42,7 +41,7 @@
 @SelfRepeatingAnno
 @Retention(RetentionPolicy.RUNTIME)
 @SelfRepeatingAnno
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @interface SelfRepeatingAnno {}
 
 public class SelfRepeatingAnnotations {
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,9 @@
 
 import java.lang.annotation.*;
 
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
 @interface Foo {}
 
-@ContainerFor(Foo.class)
 @interface Foos {
     Foo[] value();
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(UseWrongContainedBy.class)
-@interface Foos {
-    UseWrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface UseWrongContainedBy {}
-
-@UseWrongContainedBy @UseWrongContainedBy
-@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
-    UseWrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface UseWrongContainerFor {}
-
-@UseWrongContainerFor @UseWrongContainerFor
-@interface Foo {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongRepeatable.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@interface Foos {
+    UseWrongRepeatable[] value();
+}
+
+@Repeatable(Target.class)
+public @interface UseWrongRepeatable {}
+
+@UseWrongRepeatable @UseWrongRepeatable
+@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail WrongContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(WrongContainedBy.class)
-@interface Foos {
-    WrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface WrongContainedBy {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @summary Smoke test for repeating annotations
- * @compile/fail WrongContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
-    WrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java	Sun Jan 20 23:39:11 2013 -0800
@@ -6,15 +6,13 @@
  * @compile/fail/ref=WrongReturnTypeForValue.out -XDrawDiagnostics WrongReturnTypeForValue.java
  */
 
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
 
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
 @interface Foo {
     int getNumbers();
 }
 
-@ContainerFor(Foo.class)
 @interface FooContainer{
     Foo value();     // wrong return type
 }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,4 @@
-WrongReturnTypeForValue.java:22:1: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[]
-WrongReturnTypeForValue.java:22:6: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[]
-2 errors
+WrongReturnTypeForValue.java:20:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+WrongReturnTypeForValue.java:20:6: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+WrongReturnTypeForValue.java:11:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -163,9 +163,8 @@
         String replaceStr = "/*"+type+"*/";
         StringBuilder annoData = new StringBuilder();
         annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
-                .append(Helper.ContentVars.CONTAINERFOR.getVal())
                 .append(Helper.ContentVars.CONTAINER.getVal())
-                .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                .append(Helper.ContentVars.REPEATABLE.getVal())
                 .append(Helper.ContentVars.BASE.getVal());
 
         JavaFileObject pkgInfoFile = null;
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -115,24 +115,21 @@
         switch(className) {
         case "DeprecatedonBoth":
             annoData.append(Helper.ContentVars.DEPRECATED.getVal())
-                    .append(Helper.ContentVars.CONTAINERFOR.getVal())
                     .append(Helper.ContentVars.CONTAINER.getVal())
                     .append(Helper.ContentVars.DEPRECATED.getVal())
-                    .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                    .append(Helper.ContentVars.REPEATABLE.getVal())
                     .append(Helper.ContentVars.BASE.getVal());
             break;
         case "DeprecatedonBase":
-            annoData.append(Helper.ContentVars.CONTAINERFOR.getVal())
-                    .append(Helper.ContentVars.CONTAINER.getVal())
+            annoData.append(Helper.ContentVars.CONTAINER.getVal())
                     .append(Helper.ContentVars.DEPRECATED.getVal())
-                    .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                    .append(Helper.ContentVars.REPEATABLE.getVal())
                     .append(Helper.ContentVars.BASE.getVal());
             break;
         case "DeprecatedonContainer":
             annoData.append(Helper.ContentVars.DEPRECATED.getVal())
-                    .append(Helper.ContentVars.CONTAINERFOR.getVal())
                     .append(Helper.ContentVars.CONTAINER.getVal())
-                    .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                    .append(Helper.ContentVars.REPEATABLE.getVal())
                     .append(Helper.ContentVars.BASE.getVal());
             break;
         }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,17 +93,15 @@
         switch(className) {
             case "DocumentedonBothAnno":
                 annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
-                .append(Helper.ContentVars.CONTAINERFOR.getVal())
                 .append(Helper.ContentVars.CONTAINER.getVal())
                 .append(Helper.ContentVars.DOCUMENTED.getVal())
-                .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                .append(Helper.ContentVars.REPEATABLE.getVal())
                 .append(Helper.ContentVars.BASE.getVal());
             break;
             case "DocumentedonContainer":
                 annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
-                .append(Helper.ContentVars.CONTAINERFOR.getVal())
                 .append(Helper.ContentVars.CONTAINER.getVal())
-                .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                .append(Helper.ContentVars.REPEATABLE.getVal())
                 .append(Helper.ContentVars.BASE.getVal());
             break;
         }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,15 +34,13 @@
 public class Helper {
 
     enum ContentVars {
-        IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" +
-                            "\nimport java.lang.annotation.ContainerFor;\n"),
+        IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.Repeatable;\n"),
         IMPORTDEPRECATED("import java.lang.Deprecated;\n"),
         IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"),
         IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
         IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
                         "\nimport java.lang.annotation.RetentionPolicy;\n"),
-        CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"),
-        CONTAINERFOR("@ContainerFor(Foo.class)\n"),
+        REPEATABLE("\n@Repeatable(FooContainer.class)\n"),
         CONTAINER("@interface FooContainer {\n" +"  Foo[] value();\n}\n"),
         BASE("@interface Foo {}\n"),
         REPEATABLEANNO("\n@Foo() @Foo()"),
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,17 +94,15 @@
         switch(className) {
         case "InheritedonBothAnno":
             annoData.append(Helper.ContentVars.INHERITED.getVal())
-            .append(Helper.ContentVars.CONTAINERFOR.getVal())
             .append(Helper.ContentVars.CONTAINER.getVal())
             .append(Helper.ContentVars.INHERITED.getVal())
-            .append(Helper.ContentVars.CONTAINEDBY.getVal())
+            .append(Helper.ContentVars.REPEATABLE.getVal())
             .append(Helper.ContentVars.BASE.getVal());
             break;
         case "InheritedonBase":
             annoData.append(Helper.ContentVars.INHERITED.getVal())
-            .append(Helper.ContentVars.CONTAINERFOR.getVal())
             .append(Helper.ContentVars.CONTAINER.getVal())
-            .append(Helper.ContentVars.CONTAINEDBY.getVal())
+            .append(Helper.ContentVars.REPEATABLE.getVal())
             .append(Helper.ContentVars.BASE.getVal());
             break;
         }
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,7 @@
                 new DiagnosticCollector<JavaFileObject>();
         boolean ok = compileCode(className, contents, diagnostics);
 
-        String expectedErrKey = "compiler.err.invalid.containedby" +
+        String expectedErrKey = "compiler.err.invalid.repeatable" +
                                         ".annotation.retention";
         if (!shouldCompile && !ok) {
             for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
@@ -175,10 +175,9 @@
         StringBuilder annoData = new StringBuilder();
         annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
                 .append(Helper.ContentVars.IMPORTRETENTION.getVal())
-                .append(Helper.ContentVars.CONTAINERFOR.getVal())
                 .append(replacedRetCAVal)
                 .append(Helper.ContentVars.CONTAINER.getVal())
-                .append(Helper.ContentVars.CONTAINEDBY.getVal())
+                .append(Helper.ContentVars.REPEATABLE.getVal())
                 .append(replacedRetBaseVal)
                 .append(Helper.ContentVars.BASE.getVal());
 
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Sun Jan 20 23:39:11 2013 -0800
@@ -1,13 +1,14 @@
 compiler.err.already.annotated                          # internal compiler error?
 compiler.err.already.defined.this.unit                  # seems to be masked by compiler.err.duplicate.class
 compiler.err.annotation.value.not.allowable.type        # cannot happen: precluded by complete type-specific tests
+compiler.err.bad.functional.intf.anno                   # seems to be masked by compiler.err.annotation.type.not.applicable
 compiler.err.cant.read.file                             # (apt.JavaCompiler?)
 compiler.err.cant.select.static.class.from.param.type
 compiler.err.dc.unterminated.string                     # cannot happen
 compiler.err.illegal.char.for.encoding
-compiler.err.invalid.containedby.annotation             # should not happen
-compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
-compiler.err.invalid.containedby.annotation.multiple.values # can't happen
+compiler.err.invalid.repeatable.annotation              # should not happen
+compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen
+compiler.err.invalid.repeatable.annotation.multiple.values # can't happen
 compiler.err.io.exception                               # (javah.JavahTask?)
 compiler.err.limit.code                                 # Code
 compiler.err.limit.code.too.large.for.try.stmt          # Gen
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.bad.functional.intf.anno.1
+// key: compiler.misc.not.a.functional.intf
+
+@FunctionalInterface
+class BadFunctionalIntfAnno { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.not.documented
-
-import java.lang.annotation.*;
-
-@Documented
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByDocumentedMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.not.inherited
-
-import java.lang.annotation.*;
-
-@Inherited
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByInheritedMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.no.value
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos {}
-
-@Anno
-@Anno
-class ContainedByNoValue { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.elem.nondefault
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); String foo(); }
-
-class ContainedByNonDefault { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.retention
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByRetentionMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.incompatible.target
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@Target(ElementType.METHOD)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-class ContainedByTargetMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.value.return
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { String value(); }
-
-@Anno
-@Anno
-class ContainedByWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,17 +22,16 @@
  */
 
 // key: compiler.err.duplicate.annotation.invalid.repeated
-// key: compiler.err.invalid.containedby.annotation.elem.nondefault
-//
+// key: compiler.err.invalid.repeatable.annotation.elem.nondefault
+
 // We need an almost valid containing annotation. The easiest way to get
 // one close enough to valid is by forgetting a default.
 
 import java.lang.annotation.*;
 
-@ContainedBy(Annos.class)
+@Repeatable(Annos.class)
 @interface Anno { }
 
-@ContainerFor(Anno.class)
 @interface Annos { Anno[] value(); String foo(); }
 
 @Anno
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableDocumentedMismatch.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.not.documented
+
+import java.lang.annotation.*;
+
+@Documented
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableDocumentedMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableInheritedMismatch.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.not.inherited
+
+import java.lang.annotation.*;
+
+@Inherited
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableInheritedMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableNoValue.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.no.value
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos {}
+
+@Anno
+@Anno
+class RepeatableNoValue { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableNonDefault.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.elem.nondefault
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); String foo(); }
+
+class RepeatableNonDefault { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableRetentionMismatch.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.retention
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableRetentionMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableTargetMismatch.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.incompatible.target
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@Target(ElementType.METHOD)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+class RepeatableTargetMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableWrongValueType.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.value.return
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { String value(); }
+
+@Anno
+@Anno
+class RepeatableWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,14 +21,13 @@
  * questions.
  */
 
-// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present
+// key: compiler.err.invalid.repeatable.annotation.repeated.and.container.present
 
 import java.lang.annotation.*;
 
-@ContainedBy(Annos.class)
+@Repeatable(Annos.class)
 @interface Anno { }
 
-@ContainerFor(Anno.class)
 @interface Annos { Anno[] value(); }
 
 @Anno
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnderscoreAsIdentifier.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.underscore.as.identifier
+
+class UnderscoreAsIdentifier {
+    String _ = null;
+}
--- a/langtools/test/tools/javac/diags/examples/WrongContainedBy.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.container.no.containerfor
-// key: compiler.err.invalid.container.wrong.containedby
-
-import java.lang.annotation.*;
-
-@ContainerFor(WrongContainedBy.class)
-@interface Foos {
-    WrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface WrongContainedBy {}
--- a/langtools/test/tools/javac/diags/examples/WrongContainerFor.java	Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.container.wrong.containerfor
-// key: compiler.err.invalid.container.no.containedby
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
-    WrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/lambda/BadConv03.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/BadConv03.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
+BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: BadConv03.B, (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
 1 error
--- a/langtools/test/tools/javac/lambda/BadLambdaPos.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/BadLambdaPos.out	Sun Jan 20 23:39:11 2013 -0800
@@ -4,6 +4,6 @@
 BadLambdaPos.java:23:18: compiler.err.unexpected.lambda
 BadLambdaPos.java:23:34: compiler.err.unexpected.lambda
 BadLambdaPos.java:24:21: compiler.err.unexpected.lambda
-BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
 8 errors
--- a/langtools/test/tools/javac/lambda/BadTargetType.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/BadTargetType.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
-BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
-BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
+BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
 4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary smoke test for functional interface annotation
+ * @compile/fail/ref=FunctionalInterfaceAnno.out -XDrawDiagnostics FunctionalInterfaceAnno.java
+ */
+class FunctionalInterfaceAnno {
+    @FunctionalInterface
+    static class A { } //not an interface
+
+    @FunctionalInterface
+    static abstract class B { } //not an interface
+
+    @FunctionalInterface
+    enum C { } //not an interface
+
+    @FunctionalInterface
+    @interface D { } //not an interface
+
+    @FunctionalInterface
+    interface E { } //no abstracts
+
+    @FunctionalInterface
+    interface F { default void m() { } } //no abstracts
+
+    @FunctionalInterface
+    interface G { String toString(); } //no abstracts
+
+    @FunctionalInterface
+    interface H { void m(); void n(); } //incompatible abstracts
+
+    @FunctionalInterface
+    interface I { void m(); } //ok
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,9 @@
+FunctionalInterfaceAnno.java:7:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.A)
+FunctionalInterfaceAnno.java:10:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.B)
+FunctionalInterfaceAnno.java:13:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.C)
+FunctionalInterfaceAnno.java:16:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.D)
+FunctionalInterfaceAnno.java:19:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.E, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.E))
+FunctionalInterfaceAnno.java:22:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.F, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.F))
+FunctionalInterfaceAnno.java:25:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.G, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.G))
+FunctionalInterfaceAnno.java:28:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.H, (compiler.misc.incompatible.abstracts: kindname.interface, FunctionalInterfaceAnno.H))
+8 errors
--- a/langtools/test/tools/javac/lambda/Intersection01.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/Intersection01.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
-Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
 2 errors
--- a/langtools/test/tools/javac/lambda/LambdaConv09.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/LambdaConv09.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
-LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
-LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
-LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
-LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
+LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo1, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
+LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo2, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
+LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo3, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
+LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo5, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
 4 errors
--- a/langtools/test/tools/javac/lambda/LambdaExpr10.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/LambdaExpr10.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,9 +1,9 @@
-LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
 LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
 LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
 8 errors
--- a/langtools/test/tools/javac/lambda/LambdaParserTest.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java	Sun Jan 20 23:39:11 2013 -0800
@@ -23,8 +23,7 @@
 
 /*
  * @test
- * @bug 7115050
- * @bug 8003280
+ * @bug 7115050 8003280 8005852
  * @summary Add lambda tests
  *  Add parser support for lambda expressions
  * @library ../lib
@@ -46,12 +45,12 @@
     enum LambdaKind {
         NILARY_EXPR("()->x"),
         NILARY_STMT("()->{ return x; }"),
-        ONEARY_SHORT_EXPR("x->x"),
-        ONEARY_SHORT_STMT("x->{ return x; }"),
-        ONEARY_EXPR("(#M1 #T1 x)->x"),
-        ONEARY_STMT("(#M1 #T1 x)->{ return x; }"),
-        TWOARY_EXPR("(#M1 #T1 x, #M2 #T2 y)->x"),
-        TWOARY_STMT("(#M1 #T1 x, #M2 #T2 y)->{ return x; }");
+        ONEARY_SHORT_EXPR("#PN->x"),
+        ONEARY_SHORT_STMT("#PN->{ return x; }"),
+        ONEARY_EXPR("(#M1 #T1 #PN)->x"),
+        ONEARY_STMT("(#M1 #T1 #PN)->{ return x; }"),
+        TWOARY_EXPR("(#M1 #T1 #PN, #M2 #T2 y)->x"),
+        TWOARY_STMT("(#M1 #T1 #PN, #M2 #T2 y)->{ return x; }");
 
         String lambdaTemplate;
 
@@ -60,11 +59,12 @@
         }
 
         String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2,
-                ModifierKind mk1, ModifierKind mk2) {
+                ModifierKind mk1, ModifierKind mk2, LambdaParameterName pn) {
             return lambdaTemplate.replaceAll("#M1", mk1.modifier)
                     .replaceAll("#M2", mk2.modifier)
                     .replaceAll("#T1", pk1.parameterType)
-                    .replaceAll("#T2", pk2.parameterType);
+                    .replaceAll("#T2", pk2.parameterType)
+                    .replaceAll("#PN", pn.nameStr);
         }
 
         int arity() {
@@ -87,6 +87,17 @@
         }
     }
 
+    enum LambdaParameterName {
+        IDENT("x"),
+        UNDERSCORE("_");
+
+        String nameStr;
+
+        LambdaParameterName(String nameStr) {
+            this.nameStr = nameStr;
+        }
+    }
+
     enum LambdaParameterKind {
         IMPLICIT(""),
         EXPLIICT_SIMPLE("A"),
@@ -151,8 +162,8 @@
         }
 
         String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2,
-                ModifierKind mk1, ModifierKind mk2, LambdaKind lk, SubExprKind sk) {
-            return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2))
+                ModifierKind mk1, ModifierKind mk2, LambdaKind lk, LambdaParameterName pn, SubExprKind sk) {
+            return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2, pn))
                     .replaceAll("#S", sk.subExpression);
         }
     }
@@ -174,25 +185,27 @@
 
     public static void main(String... args) throws Exception {
         for (LambdaKind lk : LambdaKind.values()) {
-            for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
-                if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
-                    continue;
-                for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
-                    if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
+            for (LambdaParameterName pn : LambdaParameterName.values()) {
+                for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
+                    if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
                         continue;
-                    for (ModifierKind mk1 : ModifierKind.values()) {
-                        if (mk1 != ModifierKind.NONE && lk.isShort())
+                    for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
+                        if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
                             continue;
-                        if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
-                            continue;
-                        for (ModifierKind mk2 : ModifierKind.values()) {
-                            if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+                        for (ModifierKind mk1 : ModifierKind.values()) {
+                            if (mk1 != ModifierKind.NONE && lk.isShort())
+                                continue;
+                            if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
                                 continue;
-                            for (SubExprKind sk : SubExprKind.values()) {
-                                for (ExprKind ek : ExprKind.values()) {
-                                    pool.execute(
-                                        new LambdaParserTest(pk1, pk2, mk1,
-                                                             mk2, lk, sk, ek));
+                            for (ModifierKind mk2 : ModifierKind.values()) {
+                                if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+                                    continue;
+                                for (SubExprKind sk : SubExprKind.values()) {
+                                    for (ExprKind ek : ExprKind.values()) {
+                                        pool.execute(
+                                            new LambdaParserTest(pk1, pk2, mk1,
+                                                                 mk2, lk, sk, ek, pn));
+                                    }
                                 }
                             }
                         }
@@ -209,6 +222,7 @@
     ModifierKind mk1;
     ModifierKind mk2;
     LambdaKind lk;
+    LambdaParameterName pn;
     SubExprKind sk;
     ExprKind ek;
     JavaSource source;
@@ -216,12 +230,13 @@
 
     LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
             ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
-            SubExprKind sk, ExprKind ek) {
+            SubExprKind sk, ExprKind ek, LambdaParameterName pn) {
         this.pk1 = pk1;
         this.pk2 = pk2;
         this.mk1 = mk1;
         this.mk2 = mk2;
         this.lk = lk;
+        this.pn = pn;
         this.sk = sk;
         this.ek = ek;
         this.source = new JavaSource();
@@ -239,7 +254,7 @@
         public JavaSource() {
             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
             source = template.replaceAll("#E",
-                    ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
+                    ek.expressionString(pk1, pk2, mk1, mk2, lk, pn, sk));
         }
 
         @Override
@@ -272,6 +287,9 @@
             errorExpected = true;
         }
 
+        errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
+                lk.arity() > 0;
+
         if (errorExpected != diagChecker.errorFound) {
             throw new Error("invalid diagnostics for source:\n" +
                 source.getCharContent(true) +
--- a/langtools/test/tools/javac/lambda/MethodReference04.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/MethodReference04.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference59.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004102
+ * @summary Add support for array constructor references
+ */
+public class MethodReference59 {
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    interface ArrayFactory<X> {
+        X make(int size);
+    }
+
+    public static void main(String[] args) {
+        ArrayFactory<int[]> factory1 = int[]::new;
+        int[] i1 = factory1.make(5);
+        assertTrue(i1.length == 5);
+        ArrayFactory<int[][]> factory2 = int[][]::new;
+        int[][] i2 = factory2.make(5);
+        assertTrue(i2.length == 5);
+        assertTrue(assertionCount == 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference60.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004102
+ * @summary Add support for array constructor references
+ * @compile/fail/ref=MethodReference60.out -XDrawDiagnostics MethodReference60.java
+ */
+public class MethodReference60 {
+
+    interface ArrayFactory<X> {
+        X make(int size);
+    }
+
+    interface BadArrayFactory1<X> {
+        X make();
+    }
+
+    interface BadArrayFactory2<X> {
+        X make(int i1, int i2);
+    }
+
+    interface BadArrayFactory3<X> {
+        X make(String s);
+    }
+
+    public static void main(String[] args) {
+        BadArrayFactory1<int[]> factory1 = int[]::new; //param mismatch
+        BadArrayFactory2<int[]> factory2 = int[]::new; //param mismatch
+        BadArrayFactory3<int[]> factory3 = int[]::new; //param mismatch
+        ArrayFactory<Integer> factory4 = int[]::new; //return type mismatch
+        ArrayFactory<Integer[]> factory5 = int[]::new; //return type mismatch
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference60.out	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,6 @@
+MethodReference60.java:49:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, compiler.misc.no.args, kindname.class, Array, (compiler.misc.arg.length.mismatch)))
+MethodReference60.java:50:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, int,int, kindname.class, Array, (compiler.misc.arg.length.mismatch)))
+MethodReference60.java:51:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, java.lang.String, kindname.class, Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, int))))
+MethodReference60.java:52:42: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer))
+MethodReference60.java:53:44: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer[]))
+5 errors
--- a/langtools/test/tools/javac/lambda/TargetType17.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/TargetType17.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,9 +1,9 @@
-TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: byte)
+TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: short)
+TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: int)
+TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: long)
+TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: float)
+TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: double)
+TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: char)
+TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: boolean)
 8 errors
--- a/langtools/test/tools/javac/lambda/TargetType43.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/TargetType43.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
-TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
 TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
-TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
 TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
 4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/WarnUnderscoreAsIdent.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Check usages of underscore as identifier generate warnings
+ * @compile/fail/ref=WarnUnderscoreAsIdent.out -XDrawDiagnostics -Werror WarnUnderscoreAsIdent.java
+ */
+package _._;
+
+import _._;
+
+class _ {
+    String _ = null;
+    void _(String _) { }
+    void testLocal() {
+        String _ = null;
+    }
+    void testFor() {
+        for (int _ = 0; _ < 10; _++);
+    }
+    void testTry() {
+        try { } catch (Throwable _) { }
+    }
+    void testLabel() {
+        _:
+        for (;;) {
+            break _;
+        }
+        _:
+        for (;;) {
+            continue _;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/WarnUnderscoreAsIdent.out	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,20 @@
+WarnUnderscoreAsIdent.java:29:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:29:11: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:8: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:33:7: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:34:12: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:37:16: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:18: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:25: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:33: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:43:34: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:46:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:48:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:50:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:52:22: compiler.warn.underscore.as.identifier
+- compiler.err.warnings.and.werror
+1 error
+17 warnings
--- a/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
+LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: QooRoo, (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
 1 error
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, Planet))
+NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: Planet, (compiler.misc.no.abstracts: kindname.interface, Planet))
 1 error
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,9 +1,9 @@
-NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
-NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
-NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
 8 errors
--- a/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: AbstractClass_neg.SAM)
 1 error
--- a/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out	Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
 1 error
--- a/langtools/test/tools/javadoc/6958836/Test.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/6958836/Test.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,7 @@
         // Force en_US locale in lieu of something like -XDrawDiagnostics.
         // For some reason, this must be the first option when used.
         opts.addAll(list("-locale", "en_US"));
+        opts.add("-Xdoclint:none");
         opts.addAll(list("-classpath", System.getProperty("test.src")));
         opts.addAll(list("-d", testOutDir.getPath()));
         opts.addAll(testOpts);
--- a/langtools/test/tools/javadoc/6964914/Test.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/6964914/Test.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
     void javadoc(String path, String expect) {
         File testSrc = new File(System.getProperty("test.src"));
         String[] args = {
+            "-Xdoclint:none",
             "-source", "1.4", // enables certain Parser warnings
             "-bootclasspath", System.getProperty("sun.boot.class.path"),
             "-classpath", ".",
--- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,7 @@
         Process p = new ProcessBuilder()
             .command(javadoc.getPath(),
                 "-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"),
+                "-Xdoclint:none",
                 "-package",
                 new File(testSrc, thisClassName + ".java").getPath())
             .redirectErrorStream(true)
--- a/langtools/test/tools/javadoc/MaxWarns.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/MaxWarns.java	Sun Jan 20 23:39:11 2013 -0800
@@ -74,7 +74,7 @@
     String javadoc(File f) {
         StringWriter sw = new StringWriter();
         PrintWriter pw = new PrintWriter(sw);
-        String[] args = { "-d", "api", f.getPath() };
+        String[] args = { "-Xdoclint:none", "-d", "api", f.getPath() };
         int rc = com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw,
                 com.sun.tools.doclets.standard.Standard.class.getName(), args);
         pw.flush();
--- a/langtools/test/tools/javadoc/T6551367.java	Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/T6551367.java	Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
             File source = new File(testSrc, file);
             int rc = execute("javadoc", "T6551367",
               T6551367.class.getClassLoader(),
-              new String[]{source.getPath(), "-d", destDir.getAbsolutePath()});
+              new String[]{"-Xdoclint:none", source.getPath(), "-d", destDir.getAbsolutePath()});
             if (rc != 0)
                 throw new Error("unexpected exit from javadoc: " + rc);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/doclint/DocLintTest.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004834
+ * @summary Add doclint support into javadoc
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.tools.Diagnostic;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import static javax.tools.Diagnostic.Kind.*;
+
+import com.sun.tools.javac.main.Main;
+
+public class DocLintTest {
+    public static void main(String... args) throws Exception {
+        new DocLintTest().run();
+    }
+
+    DocumentationTool javadoc;
+    StandardJavaFileManager fm;
+    JavaFileObject file;
+
+    final String code =
+        /* 01 */    "/** Class comment. */\n" +
+        /* 02 */    "public class Test {\n" +
+        /* 03 */    "    /** Method comment. */\n" +
+        /* 04 */    "    public void method() { }\n" +
+        /* 05 */    "\n" +
+        /* 06 */    "    /** Syntax < error. */\n" +
+        /* 07 */    "    private void syntaxError() { }\n" +
+        /* 08 */    "\n" +
+        /* 09 */    "    /** @see DoesNotExist */\n" +
+        /* 10 */    "    protected void referenceError() { }\n" +
+        /* 11 */    "\n" +
+        /* 12 */    "    /** @return */\n" +
+        /* 13 */    "    public int emptyReturn() { return 0; }\n" +
+        /* 14 */    "}\n";
+
+    private final String rawDiags = "-XDrawDiagnostics";
+
+    private enum Message {
+        // doclint messages
+        DL_ERR6(ERROR, "Test.java:6:16: compiler.err.proc.messager: malformed HTML"),
+        DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"),
+        DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"),
+
+        // doclint messages when -XDrawDiagnostics is not in effect
+        DL_ERR9A(ERROR, "Test.java:9: error: reference not found"),
+        DL_WRN12A(WARNING, "Test.java:12: warning: no description for @return"),
+
+        // javadoc messages about bad content: these should only appear when doclint is disabled
+        JD_WRN10(WARNING, "Test.java:10: warning - Tag @see: reference not found: DoesNotExist"),
+        JD_WRN13(WARNING, "Test.java:13: warning - @return tag has no arguments."),
+
+        // javadoc messages for bad options
+        OPT_BADARG(ERROR, "javadoc: error - Invalid argument for -Xdoclint option"),
+        OPT_BADQUAL(ERROR, "javadoc: error - Access qualifiers not permitted for -Xdoclint arguments");
+
+        final Diagnostic.Kind kind;
+        final String text;
+
+        static Message get(String text) {
+            for (Message m: values()) {
+                if (m.text.equals(text))
+                    return m;
+            }
+            return null;
+        }
+
+        Message(Diagnostic.Kind kind, String text) {
+            this.kind = kind;
+            this.text = text;
+        }
+
+        @Override
+        public String toString() {
+            return "[" + kind + ",\"" + text + "\"]";
+        }
+    }
+
+    void run() throws Exception {
+        javadoc = ToolProvider.getSystemDocumentationTool();
+        fm = javadoc.getStandardFileManager(null, null, null);
+        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
+        file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) {
+            @Override
+            public CharSequence getCharContent(boolean ignoreEncoding) {
+                return code;
+            }
+        };
+
+        test(Collections.<String>emptyList(),
+                Main.Result.ERROR,
+                EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A));
+
+        test(Arrays.asList(rawDiags),
+                Main.Result.ERROR,
+                EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));
+
+        test(Arrays.asList("-Xdoclint:none"),
+                Main.Result.OK,
+                EnumSet.of(Message.JD_WRN10, Message.JD_WRN13));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint"),
+                Main.Result.ERROR,
+                EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint:all/public"),
+                Main.Result.ERROR,
+                EnumSet.of(Message.OPT_BADQUAL));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint:all", "-public"),
+                Main.Result.OK,
+                EnumSet.of(Message.DL_WRN12));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint:syntax"),
+                Main.Result.OK,
+                EnumSet.of(Message.DL_WRN12));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"),
+                Main.Result.ERROR,
+                EnumSet.of(Message.DL_ERR6, Message.DL_WRN12));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint:reference"),
+                Main.Result.ERROR,
+                EnumSet.of(Message.DL_ERR9));
+
+        test(Arrays.asList(rawDiags, "-Xdoclint:badarg"),
+                Main.Result.ERROR,
+                EnumSet.of(Message.OPT_BADARG));
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void test(List<String> opts, Main.Result expectResult, Set<Message> expectMessages) {
+        System.err.println("test: " + opts);
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        List<JavaFileObject> files = Arrays.asList(file);
+        try {
+            DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files);
+            boolean ok = t.call();
+            pw.close();
+            String out = sw.toString().replaceAll("[\r\n]+", "\n");
+            if (!out.isEmpty())
+                System.err.println(out);
+            if (ok && expectResult != Main.Result.OK) {
+                error("Compilation succeeded unexpectedly");
+            } else if (!ok && expectResult != Main.Result.ERROR) {
+                error("Compilation failed unexpectedly");
+            } else
+                check(out, expectMessages);
+        } catch (IllegalArgumentException e) {
+            System.err.println(e);
+            String expectOut = expectMessages.iterator().next().text;
+            if (expectResult != Main.Result.CMDERR)
+                error("unexpected exception caught");
+            else if (!e.getMessage().equals(expectOut)) {
+                error("unexpected exception message: "
+                        + e.getMessage()
+                        + " expected: " + expectOut);
+            }
+        }
+
+//        if (errors > 0)
+//            throw new Error("stop");
+    }
+
+    private void check(String out, Set<Message> expect) {
+        Pattern ignore = Pattern.compile("^(Building|Constructing|Generating|Loading|Standard|Starting| ) .*");
+        Pattern stats = Pattern.compile("^([1-9]+) (error|warning)(s?)");
+        Set<Message> found = EnumSet.noneOf(Message.class);
+        int e = 0, w = 0;
+        for (String line: out.split("[\r\n]+")) {
+            if (ignore.matcher(line).matches())
+                continue;
+
+            Matcher s = stats.matcher(line);
+            if (s.matches()) {
+                int i = Integer.valueOf(s.group(1));
+                if (s.group(2).equals("error"))
+                    e++;
+                else
+                    w++;
+                continue;
+            }
+
+            Message m = Message.get(line);
+            if (m == null)
+                error("Unexpected line: " + line);
+            else
+                found.add(m);
+        }
+        for (Message m: expect) {
+            if (!found.contains(m))
+                error("expected message not found: " + m.text);
+        }
+        for (Message m: found) {
+            if (!expect.contains(m))
+                error("unexpected message found: " + m.text);
+        }
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/SJavac.java	Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test all aspects of sjavac.
+ *
+ * @bug 8004658
+ * @summary Add internal smart javac wrapper to solve JEP 139
+ *
+ * @run main SJavac
+ */
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.charset.*;
+
+import com.sun.tools.sjavac.Main;
+
+public
+class SJavac {
+
+    public static void main(String... args) throws Exception {
+        URL url = SJavac.class.getClassLoader().getResource("com/sun/tools/sjavac/Main.class");
+        if (url == null) {
+            // No sjavac in the classpath.
+            System.out.println("pass by default");
+            return;
+        }
+
+        SJavac s = new SJavac();
+        s.test();
+    }
+
+    FileSystem defaultfs = FileSystems.getDefault();
+
+    // Where to put generated sources that will
+    // test aspects of sjavac, ie JTWork/scratch/gensrc
+    Path gensrc;
+    // More gensrc dirs are used to test merging of serveral source roots.
+    Path gensrc2;
+    Path gensrc3;
+
+    // Where to put compiled classes.
+    Path bin;
+    // Where to put c-header files.
+    Path headers;
+
+    // The sjavac compiler.
+    Main main = new Main();
+
+    // Remember the previous bin and headers state here.
+    Map<String,Long> previous_bin_state;
+    Map<String,Long> previous_headers_state;
+
+    public void test() throws Exception {
+        gensrc = defaultfs.getPath("gensrc");
+        gensrc2 = defaultfs.getPath("gensrc2");
+        gensrc3 = defaultfs.getPath("gensrc3");
+        bin = defaultfs.getPath("bin");
+        headers = defaultfs.getPath("headers");
+
+        Files.createDirectory(gensrc);
+        Files.createDirectory(gensrc2);
+        Files.createDirectory(gensrc3);
+        Files.createDirectory(bin);
+        Files.createDirectory(headers);
+
+        initialCompile();
+        incrementalCompileNoChanges();
+        incrementalCompileDroppingClasses();
+        incrementalCompileWithChange();
+        incrementalCompileDropAllNatives();
+        incrementalCompileAddNative();
+        incrementalCompileChangeNative();
+        compileWithOverrideSource();
+        compileWithInvisibleSources();
+        compileCircularSources();
+
+        delete(gensrc);
+        delete(gensrc2);
+        delete(gensrc3);
+        delete(bin);
+    }
+
+    void initialCompile() throws Exception {
+        System.out.println("\nInitial compile of gensrc.");
+        System.out.println("----------------------------");
+        populate(gensrc,
+            "alfa/AINT.java",
+            "package alfa; public interface AINT { void aint(); }",
+
+            "alfa/A.java",
+            "package alfa; public class A implements AINT { "+
+                 "public final static int DEFINITION = 17; public void aint() { } }",
+
+            "alfa/AA.java",
+            "package alfa;"+
+            "// A package private class, not contributing to the public api.\n"+
+            "class AA {"+
+            "   // A properly nested static inner class.\n"+
+            "    static class AAA { }\n"+
+            "    // A properly nested inner class.\n"+
+            "    class AAAA { }\n"+
+            "    Runnable foo() {\n"+
+            "        // A proper anonymous class.\n"+
+            "        return new Runnable() { public void run() { } };\n"+
+            "    }\n"+
+            "    AAA aaa;\n"+
+            "    AAAA aaaa;\n"+
+            "    AAAAA aaaaa;\n"+
+            "}\n"+
+            "class AAAAA {\n"+
+            "    // A bad auxiliary class, but no one is referencing it\n"+
+            "    // from outside of this source file, therefore it is ok.\n"+
+            "}\n",
+
+            "beta/BINT.java",
+            "package beta;public interface BINT { void foo(); }",
+
+            "beta/B.java",
+            "package beta; import alfa.A; public class B {"+
+            "private int b() { return A.DEFINITION; } native void foo(); }");
+
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        previous_bin_state = collectState(bin);
+        previous_headers_state = collectState(headers);
+    }
+
+    void incrementalCompileNoChanges() throws Exception {
+        System.out.println("\nTesting that no change in sources implies no change in binaries.");
+        System.out.println("------------------------------------------------------------------");
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyEqual(new_bin_state, previous_bin_state);
+        Map<String,Long> new_headers_state = collectState(headers);
+        verifyEqual(previous_headers_state, new_headers_state);
+    }
+
+    void incrementalCompileDroppingClasses() throws Exception {
+        System.out.println("\nTesting that deleting AA.java deletes all");
+        System.out.println("generated inner class as well as AA.class");
+        System.out.println("-----------------------------------------");
+        removeFrom(gensrc, "alfa/AA.java");
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
+                                       "bin/alfa/AA$1.class",
+                                       "bin/alfa/AA$AAAA.class",
+                                       "bin/alfa/AA$AAA.class",
+                                       "bin/alfa/AAAAA.class",
+                                       "bin/alfa/AA.class");
+
+        previous_bin_state = new_bin_state;
+        Map<String,Long> new_headers_state = collectState(headers);
+        verifyEqual(previous_headers_state, new_headers_state);
+    }
+
+    void incrementalCompileWithChange() throws Exception {
+        System.out.println("\nNow update the A.java file with a new timestamps and");
+        System.out.println("new final static definition. This should trigger a recompile,");
+        System.out.println("not only of alfa, but also beta.");
+        System.out.println("But check that the generated native header was not updated!");
+        System.out.println("Since we did not modify the native api of B.");
+        System.out.println("-------------------------------------------------------------");
+
+        populate(gensrc,"alfa/A.java",
+                       "package alfa; public class A implements AINT { "+
+                 "public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
+
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+
+        verifyNewerFiles(previous_bin_state, new_bin_state,
+                         "bin/alfa/A.class",
+                         "bin/alfa/AINT.class",
+                         "bin/beta/B.class",
+                         "bin/beta/BINT.class",
+                         "bin/javac_state");
+        previous_bin_state = new_bin_state;
+
+        Map<String,Long> new_headers_state = collectState(headers);
+        verifyEqual(new_headers_state, previous_headers_state);
+    }
+
+    void incrementalCompileDropAllNatives() throws Exception {
+        System.out.println("\nNow update the B.java file with one less native method,");
+        System.out.println("ie it has no longer any methods!");
+        System.out.println("Verify that beta_B.h is removed!");
+        System.out.println("---------------------------------------------------------");
+
+        populate(gensrc,"beta/B.java",
+                       "package beta; import alfa.A; public class B {"+
+                       "private int b() { return A.DEFINITION; } }");
+
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyNewerFiles(previous_bin_state, new_bin_state,
+                         "bin/beta/B.class",
+                         "bin/beta/BINT.class",
+                         "bin/javac_state");
+        previous_bin_state = new_bin_state;
+
+        Map<String,Long> new_headers_state = collectState(headers);
+        verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state,
+                                       "headers/beta_B.h");
+        previous_headers_state = new_headers_state;
+    }
+
+    void incrementalCompileAddNative() throws Exception {
+        System.out.println("\nNow update the B.java file with a final static annotated with @Native.");
+        System.out.println("Verify that beta_B.h is added again!");
+        System.out.println("------------------------------------------------------------------------");
+
+        populate(gensrc,"beta/B.java",
+                       "package beta; import alfa.A; public class B {"+
+                       "private int b() { return A.DEFINITION; } "+
+                 "@java.lang.annotation.Native final static int alfa = 42; }");
+
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyNewerFiles(previous_bin_state, new_bin_state,
+                         "bin/beta/B.class",
+                         "bin/beta/BINT.class",
+                         "bin/javac_state");
+        previous_bin_state = new_bin_state;
+
+        Map<String,Long> new_headers_state = collectState(headers);
+        verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state,
+                                     "headers/beta_B.h");
+        previous_headers_state = new_headers_state;
+    }
+
+    void incrementalCompileChangeNative() throws Exception {
+        System.out.println("\nNow update the B.java file with a new value for the final static"+
+                           " annotated with @Native.");
+        System.out.println("Verify that beta_B.h is rewritten again!");
+        System.out.println("-------------------------------------------------------------------");
+
+        populate(gensrc,"beta/B.java",
+                       "package beta; import alfa.A; public class B {"+
+                       "private int b() { return A.DEFINITION; } "+
+                 "@java.lang.annotation.Native final static int alfa = 43; }");
+
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false", "--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyNewerFiles(previous_bin_state, new_bin_state,
+                         "bin/beta/B.class",
+                         "bin/beta/BINT.class",
+                         "bin/javac_state");
+        previous_bin_state = new_bin_state;
+
+        Map<String,Long> new_headers_state = collectState(headers);
+        verifyNewerFiles(previous_headers_state, new_headers_state,
+                         "headers/beta_B.h");
+        previous_headers_state = new_headers_state;
+    }
+
+    void compileWithOverrideSource() throws Exception {
+        System.out.println("\nNow verify that we can override sources to be compiled.");
+        System.out.println("Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc,");
+        System.out.println("only compile ok beta.B in gensrc2.");
+        System.out.println("---------------------------------------------------------------------------");
+
+        delete(gensrc);
+        delete(gensrc2);
+        delete(bin);
+        previous_bin_state = collectState(bin);
+
+        populate(gensrc,"alfa/A.java",
+                 "package alfa; import beta.B; import gamma.C; public class A { B b; C c; }",
+                 "beta/B.java",
+                 "package beta; public class B { broken",
+                 "gamma/C.java",
+                 "package gamma; public class C { }");
+
+        populate(gensrc2,
+                 "beta/B.java",
+                 "package beta; public class B { }");
+
+        compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                                     "bin/alfa/A.class",
+                                     "bin/beta/B.class",
+                                     "bin/gamma/C.class",
+                                     "bin/javac_state");
+
+        System.out.println("----- Compile with exluded beta went well!");
+        delete(bin);
+        compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+                             "--server:portfile=testserver,background=false");
+
+        System.out.println("----- Compile without exluded beta failed, as expected! Good!");
+        delete(bin);
+    }
+
+    void compileWithInvisibleSources() throws Exception {
+        System.out.println("\nNow verify that we can make sources invisible to linking (sourcepath).");
+        System.out.println("Compile gensrc and link against gensrc2 and gensrc3, however");
+        System.out.println("gensrc2 contains broken code in beta.B, thus we must exclude that package");
+        System.out.println("fortunately gensrc3 contains a proper beta.B.");
+        System.out.println("------------------------------------------------------------------------");
+
+        // Start with a fresh gensrcs and bin.
+        delete(gensrc);
+        delete(gensrc2);
+        delete(gensrc3);
+        delete(bin);
+        previous_bin_state = collectState(bin);
+
+        populate(gensrc,"alfa/A.java",
+                 "package alfa; import beta.B; import gamma.C; public class A { B b; C c; }");
+        populate(gensrc2,"beta/B.java",
+                 "package beta; public class B { broken",
+                 "gamma/C.java",
+                 "package gamma; public class C { }");
+        populate(gensrc3, "beta/B.java",
+                 "package beta; public class B { }");
+
+        compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
+                "-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
+                "--server:portfile=testserver,background=false");
+
+        System.out.println("The first compile went well!");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                                     "bin/alfa/A.class",
+                                     "bin/javac_state");
+
+        System.out.println("----- Compile with exluded beta went well!");
+        delete(bin);
+        compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
+                             "-d", "bin", "-h", "headers", "-j", "1",
+                             "--server:portfile=testserver,background=false");
+
+        System.out.println("----- Compile without exluded beta failed, as expected! Good!");
+        delete(bin);
+    }
+
+    void compileCircularSources() throws Exception {
+        System.out.println("\nNow verify that circular sources split on multiple cores can be compiled.");
+        System.out.println("---------------------------------------------------------------------------");
+
+        // Start with a fresh gensrcs and bin.
+        delete(gensrc);
+        delete(gensrc2);
+        delete(gensrc3);
+        delete(bin);
+        previous_bin_state = collectState(bin);
+
+        populate(gensrc,"alfa/A.java",
+                 "package alfa; public class A { beta.B b; }",
+                 "beta/B.java",
+                 "package beta; public class B { gamma.C c; }",
+                 "gamma/C.java",
+                 "package gamma; public class C { alfa.A a; }");
+
+        compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
+                "--server:portfile=testserver,background=false","--log=debug");
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                                     "bin/alfa/A.class",
+                                     "bin/beta/B.class",
+                                     "bin/gamma/C.class",
+                                     "bin/javac_state");
+        delete(bin);
+    }
+
+    void removeFrom(Path dir, String... args) throws IOException {
+        for (String filename : args) {
+            Path p = dir.resolve(filename);
+            Files.delete(p);
+        }
+    }
+
+    void populate(Path src, String... args) throws IOException {
+        if (!Files.exists(src)) {
+            Files.createDirectory(src);
+        }
+        String[] a = args;
+        for (int i = 0; i<a.length; i+=2) {
+            String filename = a[i];
+            String content = a[i+1];
+            Path p = src.resolve(filename);
+            Files.createDirectories(p.getParent());
+            PrintWriter out = new PrintWriter(Files.newBufferedWriter(p,
+                                                                      Charset.defaultCharset()));
+            out.println(content);
+            out.close();
+        }
+    }
+
+    void delete(Path root) throws IOException {
+        if (!Files.exists(root)) return;
+        Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+                 @Override
+                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
+                 {
+                     Files.delete(file);
+                     return FileVisitResult.CONTINUE;
+                 }
+
+                 @Override
+                 public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException
+                 {
+                     if (e == null) {
+                         if (!dir.equals(root)) Files.delete(dir);
+                         return FileVisitResult.CONTINUE;
+                     } else {
+                         // directory iteration failed
+                         throw e;
+                     }
+                 }
+            });
+    }
+
+    void compile(String... args) throws Exception {
+        int rc = main.go(args, System.out, System.err);
+        if (rc != 0) throw new Exception("Error during compile!");
+
+        // Wait a second, to get around the (temporary) problem with
+        // second resolution in the Java file api. But do not do this
+        // on windows where the timestamps work.
+        long in_a_sec = System.currentTimeMillis()+1000;
+        while (in_a_sec > System.currentTimeMillis()) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    void compileExpectFailure(String... args) throws Exception {
+        int rc = main.go(args, System.out, System.err);
+        if (rc == 0) throw new Exception("Expected error during compile! Did not fail!");
+    }
+
+    Map<String,Long> collectState(Path dir) throws IOException
+    {
+        final Map<String,Long> files = new HashMap<>();
+        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+                 @Override
+                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                   throws IOException
+                 {
+                     files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis()));
+                     return FileVisitResult.CONTINUE;
+                 }
+            });
+        return files;
+    }
+
+    void verifyThatFilesHaveBeenRemoved(Map<String,Long> from,
+                                        Map<String,Long> to,
+                                        String... args) throws Exception {
+
+        Set<String> froms = from.keySet();
+        Set<String> tos = to.keySet();
+
+        if (froms.equals(tos)) {
+            throw new Exception("Expected new state to have fewer files than previous state!");
+        }
+
+        for (String t : tos) {
+            if (!froms.contains(t)) {
+                throw new Exception("Expected "+t+" to exist in previous state!");
+            }
+        }
+
+        for (String f : args) {
+            f = f.replace("/", File.separator);
+            if (!froms.contains(f)) {
+                throw new Exception("Expected "+f+" to exist in previous state!");
+            }
+            if (tos.contains(f)) {
+                throw new Exception("Expected "+f+" to have been removed from the new state!");
+            }
+        }
+
+        if (froms.size() - args.length != tos.size()) {
+            throw new Exception("There are more removed files than the expected list!");
+        }
+    }
+
+    void verifyThatFilesHaveBeenAdded(Map<String,Long> from,
+                                      Map<String,Long> to,
+                                      String... args) throws Exception {
+
+        Set<String> froms = from.keySet();
+        Set<String> tos = to.keySet();
+
+        if (froms.equals(tos)) {
+            throw new Exception("Expected new state to have more files than previous state!");
+        }
+
+        for (String t : froms) {
+            if (!tos.contains(t)) {
+                throw new Exception("Expected "+t+" to exist in new state!");
+            }
+        }
+
+        for (String f : args) {
+            f = f.replace("/", File.separator);
+            if (!tos.contains(f)) {
+                throw new Exception("Expected "+f+" to have been added to new state!");
+            }
+            if (froms.contains(f)) {
+                throw new Exception("Expected "+f+" to not exist in previous state!");
+            }
+        }
+
+        if (froms.size() + args.length != tos.size()) {
+            throw new Exception("There are more added files than the expected list!");
+        }
+    }
+
+    void verifyNewerFiles(Map<String,Long> from,
+                          Map<String,Long> to,
+                          String... args) throws Exception {
+        if (!from.keySet().equals(to.keySet())) {
+            throw new Exception("Expected the set of files to be identical!");
+        }
+        Set<String> files = new HashSet<String>();
+        for (String s : args) {
+            files.add(s.replace("/", File.separator));
+        }
+        for (String fn : from.keySet()) {
+            long f = from.get(fn);
+            long t = to.get(fn);
+            if (files.contains(fn)) {
+                if (t <= f) {
+                    throw new Exception("Expected "+fn+" to have a more recent timestamp!");
+                }
+            } else {
+                if (t != f) {
+                    throw new Exception("Expected "+fn+" to have the same timestamp!");
+                }
+            }
+        }
+    }
+
+    String print(Map<String,Long> m) {
+        StringBuilder b = new StringBuilder();
+        Set<String> keys = m.keySet();
+        for (String k : keys) {
+            b.append(k+" "+m.get(k)+"\n");
+        }
+        return b.toString();
+    }
+
+    void verifyEqual(Map<String,Long> from, Map<String,Long> to) throws Exception {
+        if (!from.equals(to)) {
+            System.out.println("FROM---"+print(from));
+            System.out.println("TO-----"+print(to));
+            throw new Exception("The dir should not differ! But it does!");
+        }
+    }
+}