diff --git a/langtools/.hgtags b/langtools/.hgtags
index 4673f14..fc29482 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -330,3 +330,4 @@
 7ef2c66892a3af15540c2800104c660c4f7f45e9 jdk9-b85
 130a7c2a85900dde04e119bc36853b73146e3414 jdk9-b86
 45f796d8cdcd8dbde5d4d660c3e749a14c923e6d jdk9-b87
+ac57d80b205db48d726084ade228e0199735831b jdk9-b88
diff --git a/langtools/make/build.properties b/langtools/make/build.properties
index 9bb5f50..d4d1daa 100644
--- a/langtools/make/build.properties
+++ b/langtools/make/build.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -47,11 +47,21 @@
 boot.javac.target = 8
 
 #configuration of submodules (share by both the bootstrap and normal compilation):
-langtools.modules=java.compiler:jdk.compiler:jdk.jdeps:jdk.javadoc
+langtools.modules=java.compiler:jdk.compiler:jdk.jdeps:jdk.javadoc:jdk.jshell:jdk.internal.le:jdk.jdi
 java.compiler.dependencies=
 jdk.compiler.dependencies=java.compiler
 jdk.javadoc.dependencies=java.compiler:jdk.compiler
 jdk.jdeps.dependencies=java.compiler:jdk.compiler
+jdk.internal.le.dependencies=
+jdk.jdi.dependencies=
+jdk.jshell.dependencies=java.compiler:jdk.internal.le:jdk.compiler:jdk.jdi
+
+tool.javac.main.class=com.sun.tools.javac.Main
+tool.javadoc.main.class=com.sun.tools.javadoc.Main
+tool.javap.main.class=com.sun.tools.javap.Main
+tool.javah.main.class=com.sun.tools.javah.Main
+tool.sjavac.main.class=com.sun.tools.sjavac.Main
+tool.jshell.main.class=jdk.internal.jshell.tool.JShellTool
 
 javac.resource.includes = \
         com/sun/tools/javac/resources/compiler.properties
diff --git a/langtools/make/build.xml b/langtools/make/build.xml
index 1876100..051eae5 100644
--- a/langtools/make/build.xml
+++ b/langtools/make/build.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
  This code is free software; you can redistribute it and/or modify it
@@ -172,6 +172,7 @@
         <build-tool name="javap"/>
         <build-tool name="javah"/>
         <build-tool name="sjavac"/>
+        <build-tool name="jshell"/>
     </target>
 
     <target name="build-all-classes" depends="-def-build-all-module-classes,build-bootstrap-javac-classes">
@@ -417,10 +418,14 @@
         <copy todir=".idea" >
             <fileset dir="make/intellij" excludes="**/src/**"/>
         </copy>
-        <condition property="jtreg.idea.home" value="${jtreg.home}" else = "[jtreg.home]">
+        <condition property="idea.jtreg.home" value="${jtreg.home}" else = "[jtreg.home]">
             <isset property="jtreg.home"/>
         </condition>
-        <replace file=".idea/ant.xml" token="@@@" value="${jtreg.idea.home}"/>
+        <condition property="idea.target.jdk" value="${target.java.home}" else = "$JDKPath$">
+            <isset property="target.java.home"/>
+        </condition>
+        <replace file=".idea/ant.xml" token="@IDEA_JTREG_HOME@" value="${idea.jtreg.home}"/>
+        <replace file=".idea/ant.xml" token="@IDEA_TARGET_JDK@" value="${idea.target.jdk}"/>
         <replace file=".idea/workspace.xml" token="@FILE_SEP@" value="${file.separator}"/>
         <replace file=".idea/workspace.xml" token="@PATH_SEP@" value="${path.separator}"/>
         <mkdir dir=".idea/classes"/>
@@ -464,6 +469,9 @@
                 <build-module-jar module.name="jdk.compiler" compilation.kind="@{compilation.kind}" />
                 <build-module-jar module.name="jdk.javadoc" compilation.kind="@{compilation.kind}" />
                 <build-module-jar module.name="jdk.jdeps" compilation.kind="@{compilation.kind}" />
+                <build-module-jar module.name="jdk.internal.le" compilation.kind="@{compilation.kind}" />
+                <build-module-jar module.name="jdk.jdi" compilation.kind="@{compilation.kind}" />
+                <build-module-jar module.name="jdk.jshell" compilation.kind="@{compilation.kind}" />
             </sequential>
         </macrodef>
     </target>
@@ -502,11 +510,12 @@
             <attribute name="compilation.kind" default=""/>
             <attribute name="bin.dir" default="${@{compilation.kind}dist.bin.dir}"/>
             <attribute name="java" default="${launcher.java}"/>
+            <attribute name="main.class" default="${tool.@{name}.main.class}"/>
             <sequential>
                 <mkdir dir="@{bin.dir}"/>
                 <copy file="${make.dir}/launcher.sh-template" tofile="@{bin.dir}/@{name}">
                     <filterset begintoken="#" endtoken="#">
-                        <filter token="PROGRAM" value="@{name}"/>
+                        <filter token="PROGRAM" value="@{main.class}"/>
                         <filter token="TARGET_JAVA" value="@{java}"/>
                         <filter token="PS" value="${path.separator}"/>
                     </filterset>
@@ -529,11 +538,17 @@
                                       compilation.kind="@{compilation.kind}" />
                 <build-module-classes module.name="jdk.jdeps"
                                       compilation.kind="@{compilation.kind}" />
+                <copy-module-classes  module.name="jdk.internal.le"
+                                      compilation.kind="@{compilation.kind}" />
+                <copy-module-classes  module.name="jdk.jdi"
+                                      compilation.kind="@{compilation.kind}" />
+                <build-module-classes module.name="jdk.jshell"
+                                      compilation.kind="@{compilation.kind}" />
             </sequential>
         </macrodef>
     </target>
 
-    <target name="-def-build-module-classes" depends="-def-pcompile,-def-pparse">
+    <target name="-def-build-module-classes" depends="-def-pcompile,-def-pparse,-def-cdumper">
         <macrodef name="build-module-classes">
             <attribute name="module.name"/>
             <attribute name="compilation.kind" default=""/>
@@ -646,6 +661,18 @@
                 </copy>
             </sequential>
         </macrodef>
+        <macrodef name="copy-module-classes">
+            <attribute name="module.name"/>
+            <attribute name="compilation.kind" default=""/>
+            <attribute name="build.dir" default="${@{compilation.kind}build.dir}"/>
+            <attribute name="classes.dir" default="@{build.dir}/@{module.name}/classes"/>
+            <attribute name="java.home" default="${boot.java.home}"/>
+            <sequential>
+                <property name="classes.origin.dir" location="${target.java.home}/../../jdk/modules/@{module.name}"/>
+                <mkdir dir="@{classes.dir}"/>
+                <dumpclasses moduleName="@{module.name}" destDir="@{classes.dir}" />
+            </sequential>
+        </macrodef>
     </target>
 
     <target name="-def-pparse">
@@ -670,6 +697,25 @@
                  classpath="${build.toolclasses.dir}/"/>
     </target>
 
+    <target name="-def-cdumper">
+        <mkdir dir="${build.toolclasses.dir}"/>
+        <javac fork="true"
+               source="${boot.javac.source}"
+               target="${boot.javac.target}"
+               executable="${boot.java.home}/bin/javac"
+               srcdir="${make.tools.dir}"
+               includes="anttasks/DumpClass*"
+               destdir="${build.toolclasses.dir}/"
+               classpath="${ant.core.lib}"
+               bootclasspath="${boot.java.home}/jre/lib/rt.jar"
+               includeantruntime="false">
+            <compilerarg line="${javac.lint.opts}"/>
+        </javac>
+        <taskdef name="dumpclasses"
+                 classname="anttasks.DumpClassesTask"
+                 classpath="${build.toolclasses.dir}/:${target.java.home}/jrt-fs.jar"/>
+    </target>
+
     <target name="-do-depend" if="do.depend">
         <depend srcdir="${src.dir}:${gensrc.dir}" destdir="${classes.dir}" classpath="${classpath}"
                 cache="${depcache.dir}"/>
diff --git a/langtools/make/gensrc/Gensrc-jdk.jshell.gmk b/langtools/make/gensrc/Gensrc-jdk.jshell.gmk
new file mode 100644
index 0000000..d677309
--- /dev/null
+++ b/langtools/make/gensrc/Gensrc-jdk.jshell.gmk
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#
+
+include GensrcCommon.gmk
+
+$(eval $(call SetupVersionProperties,JSHELL_VERSION, \
+    jdk/internal/jshell/tool/resources/version.properties))
+
+$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
+    $(JSHELL_VERSION) $(JAVAH_VERSION)))
+
+all: $(COMPILE_PROPERTIES)
diff --git a/langtools/make/intellij/ant.xml b/langtools/make/intellij/ant.xml
index 46b15c2..a0570d2 100644
--- a/langtools/make/intellij/ant.xml
+++ b/langtools/make/intellij/ant.xml
@@ -5,8 +5,8 @@
       <properties>
         <property name="boot.java.home" value="$JDKPath$" />
         <property name="jtreg.tests" value="$FilePath$" />
-        <property name="target.java.home" value="$JDKPath$" />
-        <property name="jtreg.home" value="@@@" />
+        <property name="target.java.home" value="@IDEA_TARGET_JDK@" />
+        <property name="jtreg.home" value="@IDEA_JTREG_HOME@" />
         <property name="javac.debuglevel" value="source,lines,vars" />
         <property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5900,suspend=y" />
       </properties>
diff --git a/langtools/make/intellij/langtools.iml b/langtools/make/intellij/langtools.iml
index 319eb7e..582abf1 100644
--- a/langtools/make/intellij/langtools.iml
+++ b/langtools/make/intellij/langtools.iml
@@ -13,6 +13,7 @@
       <sourceFolder url="file://$MODULE_DIR$/build/bootstrap/jdk.compiler/gensrc" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/build/bootstrap/jdk.javadoc/gensrc" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/build/bootstrap/jdk.jdeps/gensrc" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/jdk.jshell/share/classes" isTestSource="false" />
     </content>
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="inheritedJdk" />
diff --git a/langtools/make/intellij/workspace.xml b/langtools/make/intellij/workspace.xml
index 8f453ea..c2d0742 100644
--- a/langtools/make/intellij/workspace.xml
+++ b/langtools/make/intellij/workspace.xml
@@ -103,6 +103,23 @@
         <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
       </method>
     </configuration>
+    <configuration default="false" name="jshell" type="Application" factoryName="Application">
+      <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+      <option name="MAIN_CLASS_NAME" value="jdk.internal.jshell.tool.JShellTool" />
+      <option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/jdk.internal.le/classes:build/jdk.jdi/classes:build/jdk.jshell/classes:build/java.compiler/classes:build/jdk.compiler/classes:build/jdk.javadoc/classes:build/jdk.jdeps/classes" />
+      <option name="PROGRAM_PARAMETERS" value="" />
+      <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <option name="ENV_VARIABLES" />
+      <option name="PASS_PARENT_ENVS" value="true" />
+      <module name="langtools" />
+      <envs />
+      <method>
+        <option name="Make" enabled="false" />
+        <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
+      </method>
+    </configuration>
     <!-- bootstrap javac -->
     <configuration default="false" name="javac (bootstrap)" type="Application" factoryName="Application">
       <option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
diff --git a/langtools/make/launcher.sh-template b/langtools/make/launcher.sh-template
index f82d610..9397525 100644
--- a/langtools/make/launcher.sh-template
+++ b/langtools/make/launcher.sh-template
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -71,4 +71,4 @@
 unset DUALCASE
 
 IFS=$nl
-"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} com.sun.tools.#PROGRAM#.Main ${toolOpts}
+"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} #PROGRAM# ${toolOpts}
diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml
index bb57ee7..9e6c4cf 100644
--- a/langtools/make/netbeans/langtools/build.xml
+++ b/langtools/make/netbeans/langtools/build.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
 
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
@@ -81,11 +81,21 @@
         the user.
     -->
 
-    <target name="run" depends="-check-target.java.home,-build-classes,-def-run,-get-tool-and-args,-setup-bootclasspath"
+    <target name="run" depends="-check-target.java.home,-build-classes,-def-run,-get-tool-and-args,-setup-bootclasspath,-def-resolve-main-class"
             description="run tool">
         <echo level="info" message="${with_bootclasspath}"/>
         <echo level="info" message="Run ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
-        <run bcp="${with_bootclasspath}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}"/>
+        <resolve-main-class tool.name="${langtools.tool.name}" />
+        <run bcp="${with_bootclasspath}" mainclass="${langtools.main.class}" args="${langtools.tool.args}"/>
+    </target>
+
+    <target name="-def-resolve-main-class">
+        <macrodef name="resolve-main-class">
+          <attribute name="tool.name"/>
+          <sequential>
+            <property name="langtools.main.class" value="${tool.@{tool.name}.main.class}"/>
+          </sequential>
+        </macrodef>
     </target>
 
     <target name="-build-classes" depends="-get-tool-if-set,-build-classes-bootstrap-javac,-build-classes-all" />
@@ -159,10 +169,11 @@
 
     <!-- Debug tool in NetBeans. -->
 
-    <target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,-setup-bootclasspath,-build-classes" if="netbeans.home">
+    <target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,-setup-bootclasspath,-build-classes,-def-resolve-main-class" if="netbeans.home">
         <echo level="info" message="Debug ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
         <start-debugger/>
-        <run bcp="${with_bootclasspath}" mainclass="com.sun.tools.${langtools.tool.name}.Main" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
+        <resolve-main-class tool.name="${langtools.tool.name}" />
+        <run bcp="${with_bootclasspath}" mainclass="${langtools.main.class}" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
     </target>
 
     <!-- Debug a selected class . -->
diff --git a/langtools/make/netbeans/langtools/nbproject/project.xml b/langtools/make/netbeans/langtools/nbproject/project.xml
index 08ffaf2..e6d79d9 100644
--- a/langtools/make/netbeans/langtools/nbproject/project.xml
+++ b/langtools/make/netbeans/langtools/nbproject/project.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
- Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
 
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
@@ -76,6 +76,11 @@
                     <type>java</type>
                     <location>${root}/src/jdk.javadoc/share/classes</location>
                 </source-folder>
+                <source-folder>
+                    <label>Source files - jdk.jshell</label>
+                    <type>java</type>
+                    <location>${root}/src/jdk.jshell/share/classes</location>
+                </source-folder>
                 <build-file>
                     <location>${root}/build/classes</location>
                 </build-file>
@@ -152,6 +157,19 @@
                         </arity>
                     </context>
                 </action>
+                <action name="compile.single">
+                    <target>compile-single</target>
+                    <property name="module.name">jdk.jshell</property>
+                    <context>
+                        <property>includes</property>
+                        <folder>${root}/src/jdk.jshell/share/classes</folder>
+                        <pattern>\.java$</pattern>
+                        <format>relative-path</format>
+                        <arity>
+                            <separated-files>,</separated-files>
+                        </arity>
+                    </context>
+                </action>
                 <action name="run">
                     <target>run</target>
                 </action>
@@ -215,6 +233,18 @@
                         </arity>
                     </context>
                 </action>
+                <action name="run.single">
+                    <target>run-single</target>
+                    <context>
+                        <property>run.classname</property>
+                        <folder>${root}/src/jdk.jshell/share/classes</folder>
+                        <pattern>\.java$</pattern>
+                        <format>java-name</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
                 <!--
  Note: NetBeans does not appear to support context menu items
  on shell scripts :-(
@@ -285,6 +315,18 @@
                         </arity>
                     </context>
                 </action>
+                <action name="debug.single">
+                    <target>debug-single</target>
+                    <context>
+                        <property>debug.classname</property>
+                        <folder>${root}/src/jdk.jshell/share/classes</folder>
+                        <pattern>\.java$</pattern>
+                        <format>java-name</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
                 <!--
  Note: NetBeans does not appear to support context menu items
  on shell scripts :-(
@@ -353,6 +395,19 @@
                         </arity>
                     </context>
                 </action>
+                <action name="debug.fix">
+                    <target>debug-fix</target>
+                    <property name="module.name">jdk.jshell</property>
+                    <context>
+                        <property>class</property>
+                        <folder>${root}/src/jdk.jshell/share/classes</folder>
+                        <pattern>\.java$</pattern>
+                        <format>relative-path-noext</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
                 <action name="javadoc">
                     <target>javadoc</target>
                 </action>
@@ -390,6 +445,10 @@
                         <location>${root}/src/jdk.javadoc/share/classes</location>
                     </source-folder>
                     <source-folder style="tree">
+                        <label>Source files - jdk.jshell</label>
+                        <location>${root}/src/jdk.jshell/share/classes</location>
+                    </source-folder>
+                    <source-folder style="tree">
                         <label>Test files</label>
                         <location>${root}/test</location>
                     </source-folder>
@@ -456,6 +515,15 @@
                 <built-to>${root}/build/jdk.javadoc/classes</built-to>
                 <source-level>1.8</source-level>
             </compilation-unit>
+            <compilation-unit>
+                <package-root>${root}/src/jdk.jshell/share/classes</package-root>
+                <package-root>${root}/build/bootstrap/jdk.jshell/gensrc</package-root>
+                <package-root>${root}/../jdk/src/jdk.internal.le/share/classes</package-root>
+                <package-root>${root}/../jdk/src/jdk.jdi/share/classes</package-root>
+                <classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes:${root}/build/jdk.internal.le/aux:${root}/build/jdk.jdi/aux:${root}/build/jdk.internal.le/classes:${root}/build/jdk.jdi/classes</classpath>
+                <built-to>${root}/build/jdk.jshell/classes</built-to>
+                <source-level>1.8</source-level>
+            </compilation-unit>
         </java-data>
     </configuration>
 </project>
diff --git a/langtools/make/tools/anttasks/DumpClassesTask.java b/langtools/make/tools/anttasks/DumpClassesTask.java
new file mode 100644
index 0000000..a6d3781
--- /dev/null
+++ b/langtools/make/tools/anttasks/DumpClassesTask.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 anttasks;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Collections;
+import java.util.stream.Stream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+public class DumpClassesTask extends Task {
+
+    private String moduleName;
+    private File dir;
+
+    public void setModuleName(String moduleName) {
+        this.moduleName = moduleName;
+    }
+
+    public void setDestDir(File dir) {
+        this.dir = dir;
+    }
+
+    @Override
+    public void execute() {
+        try (FileSystem fs = FileSystems.newFileSystem(new URI("jrt:/"), Collections.emptyMap(), DumpClassesTask.class.getClassLoader())) {
+            Path source = fs.getPath("modules", moduleName);
+            Path target = dir.toPath();
+
+            try (Stream<Path> content = Files.walk(source)) {
+                content.filter(Files :: isRegularFile)
+                       .forEach(p -> {
+                    try {
+                        Path targetFile = target.resolve(source.relativize(p).toString());
+                        if (!Files.exists(targetFile) || Files.getLastModifiedTime(targetFile).compareTo(Files.getLastModifiedTime(source)) < 0) {
+                            Files.createDirectories(targetFile.getParent());
+                            Files.copy(p, targetFile, StandardCopyOption.REPLACE_EXISTING);
+                        }
+                    } catch (IOException ex) {
+                        throw new UncheckedIOException(ex);
+                    }
+                });
+            }
+        } catch (URISyntaxException | IOException | UncheckedIOException ex) {
+            throw new BuildException(ex);
+        }
+    }
+}
diff --git a/langtools/make/tools/anttasks/SelectToolTask.java b/langtools/make/tools/anttasks/SelectToolTask.java
index db4451d..a71f9aa 100644
--- a/langtools/make/tools/anttasks/SelectToolTask.java
+++ b/langtools/make/tools/anttasks/SelectToolTask.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -88,7 +88,8 @@
         },
         JAVADOC("javadoc"),
         JAVAH("javah"),
-        JAVAP("javap");
+        JAVAP("javap"),
+        JSHELL("jshell");
 
         String toolName;
         boolean bootstrap;
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java b/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java
index f00fbb3..b85edc9 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * 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.source.doctree;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -44,6 +45,20 @@
     List<? extends DocTree> getFirstSentence();
 
     /**
+     * Returns the entire body of a documentation comment, appearing
+     * before any block tags, including the first sentence.
+     * @return body of a documentation comment first sentence inclusive
+     *
+     * @since 1.9
+     */
+    default List<? extends DocTree> getFullBody() {
+        ArrayList<DocTree> bodyList = new ArrayList<>();
+        bodyList.addAll(getFirstSentence());
+        bodyList.addAll(getBody());
+        return bodyList;
+    }
+
+    /**
      * Returns the body of a documentation comment,
      * appearing after the first sentence, and before any block tags.
      * @return the body of a documentation comment
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
index 2000a11..8a0cee6 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * 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,12 +25,15 @@
 
 package com.sun.source.util;
 
+import java.util.List;
+
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
 import javax.tools.JavaCompiler.CompilationTask;
 
 import com.sun.source.doctree.DocCommentTree;
-import javax.tools.Diagnostic;
+import com.sun.source.doctree.DocTree;
 
 /**
  * Provides access to syntax trees for doc comments.
@@ -78,6 +81,17 @@
     public abstract Element getElement(DocTreePath path);
 
     /**
+     * Returns the list of {@link DocTree} representing the first sentence of
+     * a comment.
+     *
+     * @param list the DocTree list to interrogate
+     * @return the first sentence
+     *
+     * @since 1.9
+     */
+    public abstract List<DocTree> getFirstSentence(List<? extends DocTree> list);
+
+    /**
      * Returns a utility object for accessing the source positions
      * of documentation tree nodes.
      * @return the utility object
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java
index 6f42b90..4177a5e 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/HtmlTag.java
@@ -25,19 +25,18 @@
 
 package com.sun.tools.doclint;
 
-import java.util.Set;
 import java.util.Collections;
 import java.util.EnumMap;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
-
+import java.util.Set;
 import javax.lang.model.element.Name;
 
-import static com.sun.tools.doclint.HtmlTag.Attr.*;
-
 import com.sun.tools.javac.util.StringUtils;
 
+import static com.sun.tools.doclint.HtmlTag.Attr.*;
+
 /**
  * Enum representing HTML tags.
  *
@@ -646,15 +645,14 @@
         return map;
     }
 
-    private static final Map<String,HtmlTag> index = new HashMap<>();
+    private static final Map<String, HtmlTag> index = new HashMap<>();
     static {
         for (HtmlTag t: values()) {
             index.put(t.getText(), t);
         }
     }
 
-    static HtmlTag get(Name tagName) {
+    public static HtmlTag get(Name tagName) {
         return index.get(StringUtils.toLowerCase(tagName.toString()));
     }
-
 }
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
index 7fbf3de..c41ed29 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
@@ -25,7 +25,6 @@
 
 package com.sun.tools.javac.api;
 
-import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -86,9 +85,17 @@
 import com.sun.tools.javac.tree.DCTree.DCParam;
 import com.sun.tools.javac.tree.DCTree.DCReference;
 import com.sun.tools.javac.tree.DCTree.DCText;
+import com.sun.tools.javac.tree.DocTreeMaker;
 import com.sun.tools.javac.tree.EndPosTable;
 import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCCatch;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCIdent;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.TreeCopier;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.tree.TreeMaker;
@@ -106,6 +113,7 @@
 import com.sun.tools.javac.util.Names;
 import com.sun.tools.javac.util.Pair;
 import com.sun.tools.javac.util.Position;
+
 import static com.sun.tools.javac.code.Kinds.Kind.*;
 import static com.sun.tools.javac.code.TypeTag.*;
 
@@ -132,6 +140,7 @@
     private JavacTaskImpl javacTaskImpl;
     private Names names;
     private Types types;
+    private DocTreeMaker doctreeMaker;
 
     // called reflectively from Trees.instance(CompilationTask task)
     public static JavacTrees instance(JavaCompiler.CompilationTask task) {
@@ -173,6 +182,7 @@
         memberEnter = MemberEnter.instance(context);
         names = Names.instance(context);
         types = Types.instance(context);
+        doctreeMaker = DocTreeMaker.instance(context);
 
         JavacTask t = context.get(JavacTask.class);
         if (t instanceof JavacTaskImpl)
@@ -259,7 +269,7 @@
 
         tree.accept(new DocTreeScanner<Void, Void>() {
             @Override @DefinedBy(Api.COMPILER_TREE)
- public Void scan(DocTree node, Void p) {
+            public Void scan(DocTree node, Void p) {
                 if (node != null) last[0] = node;
                 return null;
             }
@@ -356,6 +366,11 @@
         return null;
     }
 
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
+        return doctreeMaker.getFirstSentence(list);
+    }
+
     private Symbol attributeDocReference(TreePath path, DCReference ref) {
         Env<AttrContext> env = getAttrContext(path);
 
@@ -763,7 +778,6 @@
             javacTaskImpl.enter(null);
         }
 
-
         JCCompilationUnit unit = (JCCompilationUnit) path.getCompilationUnit();
         Copier copier = createCopier(treeMaker.forToplevel(unit));
 
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
index cebf019..3bbd717 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
@@ -220,11 +220,7 @@
      */
     public static final long UNION = 1L<<39;
 
-    /**
-     * Flag that marks a special kind of bridge method (the ones that
-     * come from restricted supertype bounds).
-     */
-    public static final long OVERRIDE_BRIDGE = 1L<<40;
+    // Flag bit (1L << 40) is available.
 
     /**
      * Flag that marks an 'effectively final' local variable.
@@ -383,7 +379,6 @@
         HYPOTHETICAL(Flags.HYPOTHETICAL),
         PROPRIETARY(Flags.PROPRIETARY),
         UNION(Flags.UNION),
-        OVERRIDE_BRIDGE(Flags.OVERRIDE_BRIDGE),
         EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL),
         CLASH(Flags.CLASH),
         AUXILIARY(Flags.AUXILIARY),
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
index 1b7f287..f272aa3 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -1528,9 +1528,33 @@
          *  It is assumed that both symbols have the same name.  The static
          *  modifier is ignored for this test.
          *
+         *  A quirk in the works is that if the receiver is a method symbol for
+         *  an inherited abstract method we answer false summarily all else being
+         *  immaterial. Abstract "own" methods (i.e `this' is a direct member of
+         *  origin) don't get rejected as summarily and are put to test against the
+         *  suitable criteria.
+         *
          *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
          */
         public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
+            return overrides(_other, origin, types, checkResult, true);
+        }
+
+        /** Does this symbol override `other' symbol, when both are seen as
+         *  members of class `origin'?  It is assumed that _other is a member
+         *  of origin.
+         *
+         *  Caveat: If `this' is an abstract inherited member of origin, it is
+         *  deemed to override `other' only when `requireConcreteIfInherited'
+         *  is false.
+         *
+         *  It is assumed that both symbols have the same name.  The static
+         *  modifier is ignored for this test.
+         *
+         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
+         */
+        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
+                                            boolean requireConcreteIfInherited) {
             if (isConstructor() || _other.kind != MTH) return false;
 
             if (this == _other) return true;
@@ -1550,7 +1574,7 @@
             }
 
             // check for an inherited implementation
-            if ((flags() & ABSTRACT) != 0 ||
+            if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
                     ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
                     !other.isOverridableIn(origin) ||
                     !this.isMemberOf(origin, types))
@@ -1597,6 +1621,10 @@
             }
         }
 
+        public boolean isLambdaMethod() {
+            return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
+        }
+
         /** The implementation of this (abstract) symbol in class origin;
          *  null if none exists. Synthetic methods are not considered
          *  as possible implementations.
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
index bfb03f8..4bc4fc6 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
@@ -356,7 +356,7 @@
 
             if (sym.getKind() == ElementKind.METHOD) {
                 sym.type.asMethodType().restype = type;
-            } else if (sym.getKind() == ElementKind.PARAMETER) {
+            } else if (sym.getKind() == ElementKind.PARAMETER && currentLambda == null) {
                 sym.type = type;
                 if (sym.getQualifiedName().equals(names._this)) {
                     sym.owner.type.asMethodType().recvtype = type;
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
index 6075657..34231ac 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
@@ -1117,11 +1117,11 @@
 
         @Override
         public void visitNewClass(JCNewClass tree) {
-            if (tree.def == null) {
-                // For an anonymous class instantiation the class
-                // will be visited separately.
-                super.visitNewClass(tree);
-            }
+            scan(tree.encl);
+            scan(tree.typeargs);
+            scan(tree.clazz);
+            scan(tree.args);
+            // the anonymous class instantiation if any will be visited separately.
         }
     }
 
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java
index 5a73d6f..35185e7 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ArgumentAttr.java
@@ -263,6 +263,8 @@
                 attr.memberReferenceQualifierResult(tree));
         JCMemberReference mref2 = new TreeCopier<Void>(attr.make).copy(tree);
         mref2.expr = exprTree;
+        Symbol lhsSym = TreeInfo.symbol(exprTree);
+        localEnv.info.selectSuper = lhsSym != null && lhsSym.name == lhsSym.name.table.names._super;
         Symbol res =
                 attr.rs.getMemberReference(tree, localEnv, mref2,
                         exprTree.type, tree.name);
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
index 794b649..76666ce 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -56,7 +56,6 @@
 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.DefinedBy.Api;
-import com.sun.tools.javac.util.Dependencies.AttributionKind;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
 import com.sun.tools.javac.util.List;
@@ -760,7 +759,6 @@
      */
     void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env) {
         for (JCTypeParameter tvar : typarams) {
-            dependencies.push(AttributionKind.TVAR, tvar);
             TypeVar a = (TypeVar)tvar.type;
             a.tsym.flags_field |= UNATTRIBUTED;
             a.bound = Type.noType;
@@ -775,7 +773,6 @@
                 types.setBounds(a, List.of(syms.objectType));
             }
             a.tsym.flags_field &= ~UNATTRIBUTED;
-            dependencies.pop();
         }
         for (JCTypeParameter tvar : typarams) {
             chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
@@ -2817,8 +2814,10 @@
                 //omitted as we don't know at this stage as to whether this is a
                 //raw selector (because of inference)
                 chk.validate(that.expr, env, false);
+            } else {
+                Symbol lhsSym = TreeInfo.symbol(that.expr);
+                localEnv.info.selectSuper = lhsSym != null && lhsSym.name == names._super;
             }
-
             //attrib type-arguments
             List<Type> typeargtypes = List.nil();
             if (that.typeargs != null) {
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
index f3dbb34..7e17421 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -86,7 +86,7 @@
         log = Log.instance(context);
         syms = Symtab.instance(context);
         enter = Enter.instance(context);
-        overridden = new HashMap<>();
+        bridgeSpans = new HashMap<>();
         types = Types.instance(context);
         make = TreeMaker.instance(context);
         resolve = Resolve.instance(context);
@@ -96,10 +96,12 @@
         annotate = Annotate.instance(context);
     }
 
-    /** A hashtable mapping bridge methods to the methods they override after
-     *  type erasure.
+    /** A hashtable mapping bridge methods to the pair of methods they bridge.
+     *  The bridge overrides the first of the pair after type erasure and deflects
+     *  to the second of the pair (which differs in type erasure from the one
+     *  it overrides thereby necessitating the bridge)
      */
-    Map<MethodSymbol,MethodSymbol> overridden;
+    Map<MethodSymbol, Pair<MethodSymbol, MethodSymbol>> bridgeSpans;
 
     /** Construct an attributed tree for a cast of expression to target type,
      *  unless it already has precisely that type.
@@ -294,9 +296,9 @@
             bridges.append(md);
         }
 
-        // Add bridge to scope of enclosing class and `overridden' table.
+        // Add bridge to scope of enclosing class and keep track of the bridge span.
         origin.members().enter(bridge);
-        overridden.put(bridge, meth);
+        bridgeSpans.put(bridge, new Pair<>(meth, impl));
     }
 
     private List<VarSymbol> createBridgeParams(MethodSymbol impl, MethodSymbol bridge,
@@ -344,12 +346,12 @@
         if (sym.kind == MTH &&
             sym.name != names.init &&
             (sym.flags() & (PRIVATE | STATIC)) == 0 &&
-            (sym.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC &&
+            (sym.flags() & SYNTHETIC) != SYNTHETIC &&
             sym.isMemberOf(origin, types))
         {
             MethodSymbol meth = (MethodSymbol)sym;
             MethodSymbol bridge = meth.binaryImplementation(origin, types);
-            MethodSymbol impl = meth.implementation(origin, types, true, overrideBridgeFilter);
+            MethodSymbol impl = meth.implementation(origin, types, true);
             if (bridge == null ||
                 bridge == meth ||
                 (impl != null && !bridge.owner.isSubClass(impl.owner, types))) {
@@ -365,14 +367,19 @@
                     // reflection design error.
                     addBridge(pos, meth, impl, origin, false, bridges);
                 }
-            } else if ((bridge.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) == SYNTHETIC) {
-                MethodSymbol other = overridden.get(bridge);
+            } else if ((bridge.flags() & SYNTHETIC) == SYNTHETIC) {
+                final Pair<MethodSymbol, MethodSymbol> bridgeSpan = bridgeSpans.get(bridge);
+                MethodSymbol other = bridgeSpan == null ? null : bridgeSpan.fst;
                 if (other != null && other != meth) {
                     if (impl == null || !impl.overrides(other, origin, types, true)) {
-                        // Bridge for other symbol pair was added
-                        log.error(pos, "name.clash.same.erasure.no.override",
-                                  other, other.location(origin.type, types),
-                                  meth,  meth.location(origin.type, types));
+                        // Is bridge effectively also the bridge for `meth', if so no clash.
+                        MethodSymbol target = bridgeSpan == null ? null : bridgeSpan.snd;
+                        if (target == null || !target.overrides(meth, origin, types, true, false)) {
+                            // Bridge for other symbol pair was added
+                            log.error(pos, "name.clash.same.erasure.no.override",
+                                    other, other.location(origin.type, types),
+                                    meth, meth.location(origin.type, types));
+                        }
                     }
                 }
             } else if (!bridge.overrides(meth, origin, types, true)) {
@@ -388,11 +395,6 @@
         }
     }
     // where
-        private Filter<Symbol> overrideBridgeFilter = new Filter<Symbol>() {
-            public boolean accepts(Symbol s) {
-                return (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC;
-            }
-        };
 
         /**
          * @param method The symbol for which a bridge might have to be added
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
index 872fd9c..04aaa83 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
@@ -54,7 +54,6 @@
 import static com.sun.tools.javac.code.TypeTag.ERROR;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
-import com.sun.tools.javac.util.Dependencies.AttributionKind;
 import com.sun.tools.javac.util.Dependencies.CompletionCause;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -372,7 +371,6 @@
         }
 
         private void doImport(JCImport tree) {
-            dependencies.push(AttributionKind.IMPORT, tree);
             JCFieldAccess imp = (JCFieldAccess)tree.qualid;
             Name name = TreeInfo.name(imp);
 
@@ -399,7 +397,6 @@
                     importNamed(tree.pos(), c, env, tree);
                 }
             }
-            dependencies.pop();
         }
 
         Type attribImportType(JCTree tree, Env<AttrContext> env) {
@@ -647,13 +644,7 @@
 
             if (tree.extending != null) {
                 extending = clearTypeParams(tree.extending);
-                dependencies.push(AttributionKind.EXTENDS, tree.extending);
-                try {
-                    supertype = attr.attribBase(extending, baseEnv,
-                                                true, false, true);
-                } finally {
-                    dependencies.pop();
-                }
+                supertype = attr.attribBase(extending, baseEnv, true, false, true);
             } else {
                 extending = null;
                 supertype = ((tree.mods.flags & Flags.ENUM) != 0)
@@ -671,20 +662,14 @@
             List<JCExpression> interfaceTrees = tree.implementing;
             for (JCExpression iface : interfaceTrees) {
                 iface = clearTypeParams(iface);
-                dependencies.push(AttributionKind.IMPLEMENTS, iface);
-                try {
-                    Type it = attr.attribBase(iface, baseEnv, false, true, true);
-                    if (it.hasTag(CLASS)) {
-                        interfaces.append(it);
-                        if (all_interfaces != null) all_interfaces.append(it);
-                    } else {
-                        if (all_interfaces == null)
-                            all_interfaces = new ListBuffer<Type>().appendList(interfaces);
-                        all_interfaces.append(modelMissingTypes(it, iface, true));
-
-                    }
-                } finally {
-                    dependencies.pop();
+                Type it = attr.attribBase(iface, baseEnv, false, true, true);
+                if (it.hasTag(CLASS)) {
+                    interfaces.append(it);
+                    if (all_interfaces != null) all_interfaces.append(it);
+                } else {
+                    if (all_interfaces == null)
+                        all_interfaces = new ListBuffer<Type>().appendList(interfaces);
+                    all_interfaces.append(modelMissingTypes(it, iface, true));
                 }
             }
 
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index f57b01d..10db4ef 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -1107,8 +1107,10 @@
             endAttr(alenIdx);
             acount++;
         }
-        if (options.isSet(PARAMETERS))
-            acount += writeMethodParametersAttr(m);
+        if (options.isSet(PARAMETERS)) {
+            if (!m.isLambdaMethod()) // Per JDK-8138729, do not emit parameters table for lambda bodies.
+                acount += writeMethodParametersAttr(m);
+        }
         acount += writeMemberAttrs(m);
         acount += writeParameterAttrs(m);
         endAttrs(acountIdx, acount);
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
index 039a1f4..f7dd6da 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
@@ -1697,6 +1697,11 @@
     public void visitReturn(JCReturn tree) {
         int limit = code.nextreg;
         final Env<GenContext> targetEnv;
+
+        /* Save and then restore the location of the return in case a finally
+         * is expanded (with unwind()) in the middle of our bytecodes.
+         */
+        int tmpPos = code.pendingStatPos;
         if (tree.expr != null) {
             Item r = genExpr(tree.expr, pt).load();
             if (hasFinally(env.enclMethod, env)) {
@@ -1704,17 +1709,10 @@
                 r.store();
             }
             targetEnv = unwind(env.enclMethod, env);
+            code.pendingStatPos = tmpPos;
             r.load();
             code.emitop0(ireturn + Code.truncate(Code.typecode(pt)));
         } else {
-            /*  If we have a statement like:
-             *
-             *  return;
-             *
-             *  we need to store the code.pendingStatPos value before generating
-             *  the finalizer.
-             */
-            int tmpPos = code.pendingStatPos;
             targetEnv = unwind(env.enclMethod, env);
             code.pendingStatPos = tmpPos;
             code.emitop0(return_);
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
index 60e8418..af1e623 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
@@ -26,12 +26,8 @@
 package com.sun.tools.javac.parser;
 
 import java.text.BreakIterator;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 import com.sun.source.doctree.AttributeTree.ValueKind;
 import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
@@ -40,12 +36,10 @@
 import com.sun.tools.javac.tree.DCTree;
 import com.sun.tools.javac.tree.DCTree.DCAttribute;
 import com.sun.tools.javac.tree.DCTree.DCDocComment;
-import com.sun.tools.javac.tree.DCTree.DCEndElement;
 import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
 import com.sun.tools.javac.tree.DCTree.DCErroneous;
 import com.sun.tools.javac.tree.DCTree.DCIdentifier;
 import com.sun.tools.javac.tree.DCTree.DCReference;
-import com.sun.tools.javac.tree.DCTree.DCStartElement;
 import com.sun.tools.javac.tree.DCTree.DCText;
 import com.sun.tools.javac.tree.DocTreeMaker;
 import com.sun.tools.javac.tree.JCTree;
@@ -55,9 +49,8 @@
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Names;
-import com.sun.tools.javac.util.Options;
 import com.sun.tools.javac.util.Position;
-import com.sun.tools.javac.util.StringUtils;
+
 import static com.sun.tools.javac.util.LayoutCharacters.*;
 
 /**
@@ -100,24 +93,20 @@
 
     Map<Name, TagParser> tagParsers;
 
-    DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) {
+    public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) {
         this.fac = fac;
         this.diagSource = diagSource;
         this.comment = comment;
         names = fac.names;
         m = fac.docTreeMaker;
-
-        Locale locale = (fac.locale == null) ? Locale.getDefault() : fac.locale;
-
-        Options options = fac.options;
-        boolean useBreakIterator = options.isSet("breakIterator");
-        if (useBreakIterator || !locale.getLanguage().equals(Locale.ENGLISH.getLanguage()))
-            sentenceBreaker = BreakIterator.getSentenceInstance(locale);
-
         initTagParsers();
     }
 
-    DCDocComment parse() {
+    public DocCommentParser(ParserFactory fac) {
+        this(fac, null, null);
+    }
+
+    public DCDocComment parse() {
         String c = comment.getText();
         buf = new char[c.length() + 1];
         c.getChars(0, c.length(), buf, 0);
@@ -128,54 +117,11 @@
 
         List<DCTree> body = blockContent();
         List<DCTree> tags = blockTags();
+        int pos = !body.isEmpty()
+                ? body.head.pos
+                : !tags.isEmpty() ? tags.head.pos : Position.NOPOS;
 
-        // split body into first sentence and body
-        ListBuffer<DCTree> fs = new ListBuffer<>();
-        loop:
-        for (; body.nonEmpty(); body = body.tail) {
-            DCTree t = body.head;
-            switch (t.getKind()) {
-                case TEXT:
-                    String s = ((DCText) t).getBody();
-                    int i = getSentenceBreak(s);
-                    if (i > 0) {
-                        int i0 = i;
-                        while (i0 > 0 && isWhitespace(s.charAt(i0 - 1)))
-                            i0--;
-                        fs.add(m.at(t.pos).Text(s.substring(0, i0)));
-                        int i1 = i;
-                        while (i1 < s.length() && isWhitespace(s.charAt(i1)))
-                            i1++;
-                        body = body.tail;
-                        if (i1 < s.length())
-                            body = body.prepend(m.at(t.pos + i1).Text(s.substring(i1)));
-                        break loop;
-                    } else if (body.tail.nonEmpty()) {
-                        if (isSentenceBreak(body.tail.head)) {
-                            int i0 = s.length() - 1;
-                            while (i0 > 0 && isWhitespace(s.charAt(i0)))
-                                i0--;
-                            fs.add(m.at(t.pos).Text(s.substring(0, i0 + 1)));
-                            body = body.tail;
-                            break loop;
-                        }
-                    }
-                    break;
-
-                case START_ELEMENT:
-                case END_ELEMENT:
-                    if (isSentenceBreak(t))
-                        break loop;
-                    break;
-            }
-            fs.add(t);
-        }
-
-        @SuppressWarnings("unchecked")
-        DCTree first = getFirst(fs.toList(), body, tags);
-        int pos = (first == null) ? Position.NOPOS : first.pos;
-
-        DCDocComment dc = m.at(pos).DocComment(comment, fs.toList(), body, tags);
+        DCDocComment dc = m.at(pos).DocComment(comment, body, tags);
         return dc;
     }
 
@@ -331,23 +277,28 @@
             nextChar();
             if (isIdentifierStart(ch)) {
                 Name name = readTagName();
-                skipWhitespace();
-
                 TagParser tp = tagParsers.get(name);
+
                 if (tp == null) {
-                    DCTree text = inlineText();
+                    skipWhitespace();
+                    DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_ALL);
                     if (text != null) {
                         nextChar();
                         return m.at(p).UnknownInlineTag(name, List.of(text)).setEndPos(bp);
                     }
-                } else if (tp.getKind() == TagParser.Kind.INLINE) {
-                    DCEndPosTree<?> tree = (DCEndPosTree<?>) tp.parse(p);
-                    if (tree != null) {
-                        return tree.setEndPos(bp);
-                    }
                 } else {
-                    inlineText(); // skip content
-                    nextChar();
+                    if (!tp.retainWhiteSpace) {
+                        skipWhitespace();
+                    }
+                    if (tp.getKind() == TagParser.Kind.INLINE) {
+                        DCEndPosTree<?> tree = (DCEndPosTree<?>) tp.parse(p);
+                        if (tree != null) {
+                            return tree.setEndPos(bp);
+                        }
+                    } else { // handle block tags (ex: @see) in inline content
+                        inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip content
+                        nextChar();
+                    }
                 }
             }
             return erroneous("dc.no.tag.name", p);
@@ -356,13 +307,32 @@
         }
     }
 
+    private static enum WhitespaceRetentionPolicy {
+        RETAIN_ALL,
+        REMOVE_FIRST_SPACE,
+        REMOVE_ALL
+    }
+
     /**
      * Read plain text content of an inline tag.
      * Matching pairs of { } are skipped; the text is terminated by the first
      * unmatched }. It is an error if the beginning of the next tag is detected.
      */
-    protected DCTree inlineText() throws ParseException {
-        skipWhitespace();
+    private DCTree inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException {
+        switch (whitespacePolicy) {
+            case REMOVE_ALL:
+                skipWhitespace();
+                break;
+            case REMOVE_FIRST_SPACE:
+                if (ch == ' ')
+                    nextChar();
+                break;
+            case RETAIN_ALL:
+            default:
+                // do nothing
+                break;
+
+        }
         int pos = bp;
         int depth = 1;
 
@@ -742,7 +712,8 @@
                 }
                 if (ch == '>') {
                     nextChar();
-                    return m.at(p).StartElement(name, attrs, selfClosing).setEndPos(bp);
+                    DCTree dctree = m.at(p).StartElement(name, attrs, selfClosing).setEndPos(bp);
+                    return dctree;
                 }
             }
         } else if (ch == '/') {
@@ -884,15 +855,6 @@
         return m.at(pos).Erroneous(newString(pos, i + 1), diagSource, code);
     }
 
-    @SuppressWarnings("unchecked")
-    <T> T getFirst(List<T>... lists) {
-        for (List<T> list: lists) {
-            if (list.nonEmpty())
-                return list.head;
-        }
-        return null;
-    }
-
     protected boolean isIdentifierStart(char ch) {
         return Character.isUnicodeIdentifierStart(ch);
     }
@@ -916,8 +878,11 @@
     protected Name readTagName() {
         int start = bp;
         nextChar();
-        while (bp < buflen && (Character.isUnicodeIdentifierPart(ch) || ch == '.'))
+        while (bp < buflen
+                && (Character.isUnicodeIdentifierPart(ch) || ch == '.'
+                || ch == '-' || ch == ':')) {
             nextChar();
+        }
         return names.fromChars(buf, start, bp - start);
     }
 
@@ -960,59 +925,9 @@
     }
 
     protected void skipWhitespace() {
-        while (isWhitespace(ch))
+        while (isWhitespace(ch)) {
             nextChar();
-    }
-
-    protected int getSentenceBreak(String s) {
-        if (sentenceBreaker != null) {
-            sentenceBreaker.setText(s);
-            int i = sentenceBreaker.next();
-            return (i == s.length()) ? -1 : i;
         }
-
-        // scan for period followed by whitespace
-        boolean period = false;
-        for (int i = 0; i < s.length(); i++) {
-            switch (s.charAt(i)) {
-                case '.':
-                    period = true;
-                    break;
-
-                case ' ':
-                case '\f':
-                case '\n':
-                case '\r':
-                case '\t':
-                    if (period)
-                        return i;
-                    break;
-
-                default:
-                    period = false;
-                    break;
-            }
-        }
-        return -1;
-    }
-
-
-    Set<String> htmlBlockTags = new HashSet<>(Arrays.asList(
-                    "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"));
-
-    protected boolean isSentenceBreak(Name n) {
-        return htmlBlockTags.contains(StringUtils.toLowerCase(n.toString()));
-    }
-
-    protected boolean isSentenceBreak(DCTree t) {
-        switch (t.getKind()) {
-            case START_ELEMENT:
-                return isSentenceBreak(((DCStartElement) t).getName());
-
-            case END_ELEMENT:
-                return isSentenceBreak(((DCEndElement) t).getName());
-        }
-        return false;
     }
 
     /**
@@ -1026,12 +941,21 @@
     static abstract class TagParser {
         enum Kind { INLINE, BLOCK }
 
-        Kind kind;
-        DCTree.Kind treeKind;
+        final Kind kind;
+        final DCTree.Kind treeKind;
+        final boolean retainWhiteSpace;
+
 
         TagParser(Kind k, DCTree.Kind tk) {
             kind = k;
             treeKind = tk;
+            retainWhiteSpace = false;
+        }
+
+        TagParser(Kind k, DCTree.Kind tk, boolean retainWhiteSpace) {
+            kind = k;
+            treeKind = tk;
+            this.retainWhiteSpace = retainWhiteSpace;
         }
 
         Kind getKind() {
@@ -1059,9 +983,9 @@
             },
 
             // {@code text}
-            new TagParser(Kind.INLINE, DCTree.Kind.CODE) {
+            new TagParser(Kind.INLINE, DCTree.Kind.CODE, true) {
                 public DCTree parse(int pos) throws ParseException {
-                    DCTree text = inlineText();
+                    DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
                     nextChar();
                     return m.at(pos).Code((DCText) text);
                 }
@@ -1082,7 +1006,7 @@
                         nextChar();
                         return m.at(pos).DocRoot();
                     }
-                    inlineText(); // skip unexpected content
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
                     nextChar();
                     throw new ParseException("dc.unexpected.content");
                 }
@@ -1105,7 +1029,7 @@
                         nextChar();
                         return m.at(pos).InheritDoc();
                     }
-                    inlineText(); // skip unexpected content
+                    inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content
                     nextChar();
                     throw new ParseException("dc.unexpected.content");
                 }
@@ -1130,9 +1054,9 @@
             },
 
             // {@literal text}
-            new TagParser(Kind.INLINE, DCTree.Kind.LITERAL) {
+            new TagParser(Kind.INLINE, DCTree.Kind.LITERAL, true) {
                 public DCTree parse(int pos) throws ParseException {
-                    DCTree text = inlineText();
+                    DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
                     nextChar();
                     return m.at(pos).Literal((DCText) text);
                 }
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
index 6cc7a67..9af4c19 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -973,7 +973,7 @@
          */
         protected JCExpression foldStrings(JCExpression tree) {
             if (!allowStringFolding)
-                return null;
+                return tree;
             ListBuffer<JCExpression> opStack = new ListBuffer<>();
             ListBuffer<JCLiteral> litBuf = new ListBuffer<>();
             boolean needsFolding = false;
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java
index 816959c..3a820c6 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package com.sun.tools.javac.tree;
 
-
 import javax.tools.Diagnostic;
 
 import com.sun.source.doctree.*;
@@ -39,8 +38,10 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Name;
 import com.sun.tools.javac.util.Position;
+
 import java.io.IOException;
 import java.io.StringWriter;
+
 import javax.tools.JavaFileObject;
 
 /**
@@ -104,14 +105,19 @@
     public static class DCDocComment extends DCTree implements DocCommentTree {
         public final Comment comment; // required for the implicit source pos table
 
+        public final List<DCTree> fullBody;
         public final List<DCTree> firstSentence;
         public final List<DCTree> body;
         public final List<DCTree> tags;
 
         public DCDocComment(Comment comment,
-                List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
+                            List<DCTree> fullBody,
+                            List<DCTree> firstSentence,
+                            List<DCTree> body,
+                            List<DCTree> tags) {
             this.comment = comment;
             this.firstSentence = firstSentence;
+            this.fullBody = fullBody;
             this.body = body;
             this.tags = tags;
         }
@@ -132,6 +138,11 @@
         }
 
         @DefinedBy(Api.COMPILER_TREE)
+        public List<? extends DocTree> getFullBody() {
+            return fullBody;
+        }
+
+        @DefinedBy(Api.COMPILER_TREE)
         public List<? extends DocTree> getBody() {
             return body;
         }
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java
index e38f854..4af8a81 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * 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,15 +25,15 @@
 
 package com.sun.tools.javac.tree;
 
+import java.io.IOException;
 import java.io.Writer;
+import java.util.List;
 
 import com.sun.source.doctree.*;
 import com.sun.source.doctree.AttributeTree.ValueKind;
 import com.sun.tools.javac.util.Convert;
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
-import java.io.IOException;
-import java.util.List;
 
 /**
  * Prints out a doc comment tree.
@@ -201,14 +201,10 @@
     @DefinedBy(Api.COMPILER_TREE)
     public Void visitDocComment(DocCommentTree node, Void p) {
         try {
-            List<? extends DocTree> fs = node.getFirstSentence();
-            List<? extends DocTree> b = node.getBody();
+            List<? extends DocTree> b = node.getFullBody();
             List<? extends DocTree> t = node.getBlockTags();
-            print(fs);
-            if (!fs.isEmpty() && !b.isEmpty())
-                print(" ");
             print(b);
-            if ((!fs.isEmpty() || !b.isEmpty()) && !t.isEmpty())
+            if (!b.isEmpty() && !t.isEmpty())
                 print("\n");
             print(t, "\n");
         } catch (IOException e) {
@@ -308,7 +304,10 @@
         try {
             print("{");
             printTagName(node);
-            print(" ");
+            String body = node.getBody().getBody();
+            if (!body.isEmpty() && !Character.isWhitespace(body.charAt(0))) {
+                print(" ");
+            }
             print(node.getBody());
             print("}");
         } catch (IOException e) {
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
index 2860111..64a29ac 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * 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,19 +25,62 @@
 
 package com.sun.tools.javac.tree;
 
+import java.text.BreakIterator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.ListIterator;
+import java.util.Locale;
+
 import com.sun.source.doctree.AttributeTree.ValueKind;
+import com.sun.source.doctree.DocTree;
 import com.sun.source.doctree.DocTree.Kind;
+import com.sun.source.doctree.EndElementTree;
+import com.sun.source.doctree.StartElementTree;
+import com.sun.tools.doclint.HtmlTag;
 
 import com.sun.tools.javac.parser.Tokens.Comment;
-import com.sun.tools.javac.tree.DCTree.*;
+import com.sun.tools.javac.tree.DCTree.DCAttribute;
+import com.sun.tools.javac.tree.DCTree.DCAuthor;
+import com.sun.tools.javac.tree.DCTree.DCComment;
+import com.sun.tools.javac.tree.DCTree.DCDeprecated;
+import com.sun.tools.javac.tree.DCTree.DCDocComment;
+import com.sun.tools.javac.tree.DCTree.DCDocRoot;
+import com.sun.tools.javac.tree.DCTree.DCEndElement;
+import com.sun.tools.javac.tree.DCTree.DCEntity;
+import com.sun.tools.javac.tree.DCTree.DCErroneous;
+import com.sun.tools.javac.tree.DCTree.DCIdentifier;
+import com.sun.tools.javac.tree.DCTree.DCInheritDoc;
+import com.sun.tools.javac.tree.DCTree.DCLink;
+import com.sun.tools.javac.tree.DCTree.DCLiteral;
+import com.sun.tools.javac.tree.DCTree.DCParam;
+import com.sun.tools.javac.tree.DCTree.DCReference;
+import com.sun.tools.javac.tree.DCTree.DCReturn;
+import com.sun.tools.javac.tree.DCTree.DCSee;
+import com.sun.tools.javac.tree.DCTree.DCSerial;
+import com.sun.tools.javac.tree.DCTree.DCSerialData;
+import com.sun.tools.javac.tree.DCTree.DCSerialField;
+import com.sun.tools.javac.tree.DCTree.DCSince;
+import com.sun.tools.javac.tree.DCTree.DCStartElement;
+import com.sun.tools.javac.tree.DCTree.DCText;
+import com.sun.tools.javac.tree.DCTree.DCThrows;
+import com.sun.tools.javac.tree.DCTree.DCUnknownBlockTag;
+import com.sun.tools.javac.tree.DCTree.DCUnknownInlineTag;
+import com.sun.tools.javac.tree.DCTree.DCValue;
+import com.sun.tools.javac.tree.DCTree.DCVersion;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.DiagnosticSource;
 import com.sun.tools.javac.util.JCDiagnostic;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.Pair;
 import com.sun.tools.javac.util.Position;
 
+import static com.sun.tools.doclint.HtmlTag.*;
+
 /**
  *
  *  <p><b>This is NOT part of any supported API.
@@ -50,6 +93,12 @@
     /** The context key for the tree factory. */
     protected static final Context.Key<DocTreeMaker> treeMakerKey = new Context.Key<>();
 
+    // A subset of block tags, which acts as sentence breakers, appearing
+    // anywhere but the zero'th position in the first sentence.
+    final EnumSet<HtmlTag> sentenceBreakTags;
+
+    private final BreakIterator sentenceBreaker;
+
     /** Get the TreeMaker instance. */
     public static DocTreeMaker instance(Context context) {
         DocTreeMaker instance = context.get(treeMakerKey);
@@ -71,6 +120,15 @@
         context.put(treeMakerKey, this);
         diags = JCDiagnostic.Factory.instance(context);
         this.pos = Position.NOPOS;
+        sentenceBreakTags = EnumSet.of(H1, H2, H3, H4, H5, H6, PRE, P);
+        Locale locale = (context.get(Locale.class) != null)
+                ? context.get(Locale.class)
+                : Locale.getDefault();
+        Options options = Options.instance(context);
+        boolean useBreakIterator = options.isSet("breakiterator");
+        sentenceBreaker = (useBreakIterator || !locale.getLanguage().equals(Locale.ENGLISH.getLanguage()))
+                ? BreakIterator.getSentenceInstance(locale)
+                : null;
     }
 
     /** Reassign current position.
@@ -117,9 +175,11 @@
         return tree;
     }
 
-    public DCDocComment DocComment(Comment comment, List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
-        DCDocComment tree = new DCDocComment(comment, firstSentence, body, tags);
-        tree.pos = pos;
+    public DCDocComment DocComment(Comment comment, List<DCTree> fullBody, List<DCTree> tags) {
+        final int savepos = pos;
+        Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
+        DCDocComment tree = new DCDocComment(comment, fullBody, pair.fst, pair.snd, tags);
+        this.pos = tree.pos = savepos;
         return tree;
     }
 
@@ -273,4 +333,155 @@
         tree.pos = pos;
         return tree;
     }
+
+    public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
+        Pair<List<DCTree>, List<DCTree>> pair = splitBody(list);
+        return new ArrayList<>(pair.fst);
+    }
+
+    /*
+     * Breaks up the body tags into the first sentence and its successors.
+     * The first sentence is determined with the presence of a period, block tag,
+     * or a sentence break, as returned by the BreakIterator. Trailing
+     * whitespaces are trimmed.
+     */
+    Pair<List<DCTree>, List<DCTree>> splitBody(Collection<? extends DocTree> list) {
+        ListBuffer<DCTree> body = new ListBuffer<>();
+        // split body into first sentence and body
+        ListBuffer<DCTree> fs = new ListBuffer<>();
+        if (list.isEmpty()) {
+            return new Pair<>(fs.toList(), body.toList());
+        }
+        boolean foundFirstSentence = false;
+        ArrayList<DocTree> alist = new ArrayList<>(list);
+        ListIterator<DocTree> itr = alist.listIterator();
+        while (itr.hasNext()) {
+            boolean isFirst = itr.previousIndex() == -1;
+            DocTree dt = itr.next();
+            int spos = ((DCTree)dt).pos;
+            if (foundFirstSentence) {
+                body.add((DCTree) dt);
+                continue;
+            }
+            switch (dt.getKind()) {
+                case TEXT:
+                    DCText tt = (DCText)dt;
+                    String s = tt.getBody();
+                    int sbreak = getSentenceBreak(s);
+                    if (sbreak > 0) {
+                        s = removeTrailingWhitespace(s.substring(0, sbreak));
+                        DCText text = this.at(spos).Text(s);
+                        fs.add(text);
+                        foundFirstSentence = true;
+                        int nwPos = skipWhiteSpace(tt.getBody(), sbreak);
+                        if (nwPos > 0) {
+                            DCText text2 = this.at(spos + nwPos).Text(tt.getBody().substring(nwPos));
+                            body.add(text2);
+                        }
+                        continue;
+                    } else if (itr.hasNext()) {
+                        // if the next doctree is a break, remove trailing spaces
+                        DocTree next = itr.next();
+                        boolean sbrk = isSentenceBreak(next, false);
+                        if (sbrk) {
+                            s = removeTrailingWhitespace(s);
+                            DCText text = this.at(spos).Text(s);
+                            fs.add(text);
+                            body.add((DCTree)next);
+                            foundFirstSentence = true;
+                            continue;
+                        }
+                        // reset to previous for further processing
+                        itr.previous();
+                    }
+                    break;
+                default:
+                    if (isSentenceBreak(dt, isFirst)) {
+                        body.add((DCTree)dt);
+                        foundFirstSentence = true;
+                        continue;
+                    }
+            }
+            fs.add((DCTree)dt);
+        }
+        return new Pair<>(fs.toList(), body.toList());
+    }
+
+    /*
+     * Computes the first sentence break.
+     */
+    int defaultSentenceBreak(String s) {
+        // scan for period followed by whitespace
+        int period = -1;
+        for (int i = 0; i < s.length(); i++) {
+            switch (s.charAt(i)) {
+                case '.':
+                    period = i;
+                    break;
+
+                case ' ':
+                case '\f':
+                case '\n':
+                case '\r':
+                case '\t':
+                    if (period >= 0) {
+                        return i;
+                    }
+                    break;
+
+                default:
+                    period = -1;
+                    break;
+            }
+        }
+        return -1;
+    }
+
+    int getSentenceBreak(String s) {
+        if (sentenceBreaker == null) {
+            return defaultSentenceBreak(s);
+        }
+        sentenceBreaker.setText(s);
+        return sentenceBreaker.first();
+    }
+
+    boolean isSentenceBreak(javax.lang.model.element.Name tagName) {
+        return sentenceBreakTags.contains(get(tagName));
+    }
+
+    boolean isSentenceBreak(DocTree dt, boolean isFirstDocTree) {
+        switch (dt.getKind()) {
+            case START_ELEMENT:
+                    StartElementTree set = (StartElementTree)dt;
+                    return !isFirstDocTree && ((DCTree) dt).pos > 1 && isSentenceBreak(set.getName());
+            case END_ELEMENT:
+                    EndElementTree eet = (EndElementTree)dt;
+                    return !isFirstDocTree && ((DCTree) dt).pos > 1 && isSentenceBreak(eet.getName());
+            default:
+                return false;
+        }
+    }
+
+    /*
+     * Returns the position of the the first non-white space
+     */
+    int skipWhiteSpace(String s, int start) {
+        for (int i = start; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if (!Character.isWhitespace(c)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    String removeTrailingWhitespace(String s) {
+        for (int i = s.length() - 1 ; i > 0 ; i--) {
+            char ch = s.charAt(i);
+            if (!Character.isWhitespace(ch)) {
+                return s.substring(0, i + 1);
+            }
+        }
+        return s;
+    }
 }
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java
index 773f294..f427371 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java
@@ -30,7 +30,7 @@
 import com.sun.tools.javac.code.Symbol.Completer;
 import com.sun.tools.javac.code.Symbol.CompletionFailure;
 import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.GraphUtils.DependencyKind;
 import com.sun.tools.javac.util.GraphUtils.DotVisitor;
 import com.sun.tools.javac.util.GraphUtils.NodeVisitor;
 
@@ -42,13 +42,13 @@
 import java.util.Collection;
 import java.util.EnumMap;
 import java.util.EnumSet;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.Set;
 import java.util.Stack;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.tools.JavaFileObject;
 
@@ -78,69 +78,23 @@
     }
 
     /**
-     * This enum models different kinds of attribution actions triggered during
-     * symbol completion.
-     */
-    public enum AttributionKind {
-        /**
-         * Attribution of superclass (i.e. @{code extends} clause).
-         */
-        EXTENDS {
-            @Override
-            String format(JCTree tree) {
-                return "extends " + super.format(tree);
-            }
-        },
-        /**
-         * Attribution of superinterface (i.e. an type in the @{code interface} clause).
-         */
-        IMPLEMENTS {
-            @Override
-            String format(JCTree tree) {
-                return "implements " + super.format(tree);
-            }
-        },
-        /**
-         * Attribution of an import statement
-         */
-        IMPORT,
-        /**
-         * Attribution of type-variable bound
-         */
-        TVAR {
-            @Override
-            String format(JCTree tree) {
-                return "<" + super.format(tree) + ">";
-            }
-        };
-
-        String format(JCTree tree) {
-            return tree.toString();
-        }
-    }
-
-    /**
      * Push a new completion node on the stack.
      */
     abstract public void push(ClassSymbol s, CompletionCause phase);
 
     /**
-     * Push a new attribution node on the stack.
-     */
-    abstract public void push(AttributionKind ak, JCTree t);
-
-    /**
      * Remove current dependency node from the stack.
      */
     abstract public void pop();
 
-    public enum CompletionCause {
+    public enum CompletionCause implements GraphUtils.DependencyKind {
         CLASS_READER,
         HEADER_PHASE,
         HIERARCHY_PHASE,
         IMPORTS_PHASE,
         MEMBER_ENTER,
-        MEMBERS_PHASE;
+        MEMBERS_PHASE,
+        OTHER;
     }
 
     /**
@@ -163,13 +117,8 @@
         /**
          * Register a Context.Factory to create a Dependencies.
          */
-        public static void preRegister(final Context context) {
-            context.put(dependenciesKey, new Context.Factory<Dependencies>() {
-                public Dependencies make(Context c) {
-                    Dependencies deps = new GraphDependencies(context);
-                    return deps;
-                }
-            });
+        public static void preRegister(Context context) {
+            context.put(dependenciesKey, (Context.Factory<Dependencies>) GraphDependencies::new);
         }
 
         /**
@@ -195,12 +144,11 @@
         enum DependenciesMode {
             SOURCE("source"),
             CLASS("class"),
-            REDUNDANT("redundant"),
-            SIDE_EFFECTS("side-effects");
+            REDUNDANT("redundant");
 
             final String opt;
 
-            private DependenciesMode(String opt) {
+            DependenciesMode(String opt) {
                 this.opt = opt;
             }
 
@@ -228,46 +176,19 @@
         }
 
         /**
-         * Class representing a node in the dependency graph. Nodes are of two main
-         * kinds: (i) symbol nodes, corresponding to symbol completion requests
-         * (either from source or classfile); (ii) attribution nodes, corresponding to
-         * attribution actions triggered during (source) completion.
+         * Class representing a node in the dependency graph.
          */
-        public static abstract class Node extends GraphUtils.AbstractNode<String, Node>
-                implements GraphUtils.DottableNode<String, Node> {
-
-            /**
-             * Model the dependencies between nodes.
-             */
-            public enum DependencyKind implements GraphUtils.DependencyKind {
-                /**
-                 * standard dependency - i.e. completion of the source node depends
-                 * on completion of the sink node.
-                 */
-                REQUIRES("solid"),
-                /**
-                 * soft dependencies - i.e. completion of the source node depends
-                 * on side-effects of the source node. These dependencies are meant
-                 * to capture the order in which javac processes all dependants of a given node.
-                 */
-                SIDE_EFFECTS("dashed");
-
-                final String dotStyle;
-
-                DependencyKind(String dotStyle) {
-                    this.dotStyle = dotStyle;
-                }
-            }
-
+        public static abstract class Node extends GraphUtils.AbstractNode<ClassSymbol, Node>
+                implements GraphUtils.DottableNode<ClassSymbol, Node> {
             /**
              * dependant nodes grouped by kind
              */
-            EnumMap<DependencyKind, List<Node>> depsByKind;
+            EnumMap<CompletionCause, List<Node>> depsByKind;
 
-            Node(String value) {
+            Node(ClassSymbol value) {
                 super(value);
-                this.depsByKind = new EnumMap<>(DependencyKind.class);
-                for (DependencyKind depKind : DependencyKind.values()) {
+                this.depsByKind = new EnumMap<>(CompletionCause.class);
+                for (CompletionCause depKind : CompletionCause.values()) {
                     depsByKind.put(depKind, new ArrayList<Node>());
                 }
             }
@@ -281,8 +202,7 @@
 
             @Override
             public boolean equals(Object obj) {
-                return obj instanceof Node &&
-                        data.equals(((Node) obj).data);
+                return obj instanceof Node && data.equals(((Node) obj).data);
             }
 
             @Override
@@ -292,19 +212,12 @@
 
             @Override
             public GraphUtils.DependencyKind[] getSupportedDependencyKinds() {
-                return DependencyKind.values();
+                return CompletionCause.values();
             }
 
             @Override
-            public java.util.Collection<? extends Node> getDependenciesByKind(GraphUtils.DependencyKind dk) {
-                List<Node> deps = depsByKind.get(dk);
-                if (dk == DependencyKind.REQUIRES) {
-                    return deps;
-                } else {
-                    Set<Node> temp = new HashSet<>(deps);
-                    temp.removeAll(depsByKind.get(DependencyKind.REQUIRES));
-                    return temp;
-                }
+            public java.util.Collection<? extends Node> getDependenciesByKind(DependencyKind dk) {
+                return depsByKind.get(dk);
             }
 
             @Override
@@ -317,9 +230,14 @@
             @Override
             public Properties dependencyAttributes(Node to, GraphUtils.DependencyKind dk) {
                 Properties p = new Properties();
-                p.put("style", ((DependencyKind) dk).dotStyle);
+                p.put("label", dk);
                 return p;
             }
+
+            @Override
+            public String toString() {
+                return data.getQualifiedName().toString();
+            }
         }
 
         /**
@@ -349,11 +267,9 @@
             }
 
             final Kind ck;
-            final ClassSymbol sym;
 
             CompletionNode(ClassSymbol sym) {
-                super(sym.getQualifiedName().toString());
-                this.sym = sym;
+                super(sym);
                 //infer completion kind by looking at the symbol fields
                 boolean fromClass = (sym.classfile == null && sym.sourcefile == null) ||
                         (sym.classfile != null && sym.classfile.getKind() == JavaFileObject.Kind.CLASS);
@@ -371,27 +287,7 @@
             }
 
             public ClassSymbol getClassSymbol() {
-                return sym;
-            }
-        }
-
-        /**
-         * This is a dependency node used to model attribution actions triggered during
-         * source symbol completion. The possible kinds of attribution actions are
-         * captured in {@link AttributionNode}.
-         */
-        static class AttributionNode extends Node {
-
-            AttributionNode(AttributionKind ak, JCTree tree) {
-                super(ak.format(tree));
-            }
-
-            @Override
-            public Properties nodeAttributes() {
-                Properties p = super.nodeAttributes();
-                p.put("shape", "box");
-                p.put("style", "solid");
-                return p;
+                return data;
             }
         }
 
@@ -403,25 +299,20 @@
         /**
          * map containing all dependency nodes seen so far
          */
-        Map<String, Node> dependencyNodeMap = new LinkedHashMap<>();
+        Map<ClassSymbol, Node> dependencyNodeMap = new LinkedHashMap<>();
 
         @Override
         public void push(ClassSymbol s, CompletionCause phase) {
             Node n = new CompletionNode(s);
-            if (n == push(n)) {
+            if (n == push(n, phase)) {
                 s.completer = this;
             }
         }
 
-        @Override
-        public void push(AttributionKind ak, JCTree t) {
-            push(new AttributionNode(ak, t));
-        }
-
         /**
          * Push a new dependency on the stack.
          */
-        protected Node push(Node newNode) {
+        protected Node push(Node newNode, CompletionCause cc) {
             Node cachedNode = dependencyNodeMap.get(newNode.data);
             if (cachedNode == null) {
                 dependencyNodeMap.put(newNode.data, newNode);
@@ -430,7 +321,7 @@
             }
             if (!nodeStack.isEmpty()) {
                 Node currentNode = nodeStack.peek();
-                currentNode.addDependency(Node.DependencyKind.REQUIRES, newNode);
+                currentNode.addDependency(cc, newNode);
             }
             nodeStack.push(newNode);
             return newNode;
@@ -455,10 +346,6 @@
                 //filter source completions
                 new FilterVisitor(CompletionNode.Kind.CLASS).visit(dependencyNodeMap.values(), null);
             }
-            if (dependenciesModes.contains(DependenciesMode.SIDE_EFFECTS)) {
-                //add side-effects edges
-                new SideEffectVisitor().visit(dependencyNodeMap.values(), null);
-            }
             if (dependenciesFile != null) {
                 //write to file
                 try (FileWriter fw = new FileWriter(dependenciesFile)) {
@@ -469,7 +356,7 @@
 
         @Override
         public void complete(Symbol sym) throws CompletionFailure {
-            push((ClassSymbol) sym, null);
+            push((ClassSymbol)sym, CompletionCause.OTHER);
             pop();
             sym.completer = this;
         }
@@ -484,31 +371,9 @@
         }
 
         /**
-         * This visitor is used to generate the special side-effect dependencies
-         * given a graph containing only standard dependencies.
-         */
-        private static class SideEffectVisitor extends NodeVisitor<String, Node, Void> {
-            @Override
-            public void visitNode(Node node, Void arg) {
-                //do nothing
-            }
-
-            @Override
-            public void visitDependency(GraphUtils.DependencyKind dk, Node from, Node to, Void arg) {
-                //if we are adding multiple dependencies to same node
-                //make order explicit via special 'side-effect' dependencies
-                List<Node> deps = from.depsByKind.get(dk);
-                int pos = deps.indexOf(to);
-                if (dk == Node.DependencyKind.REQUIRES && pos > 0) {
-                    to.addDependency(Node.DependencyKind.SIDE_EFFECTS, deps.get(pos - 1));
-                }
-            }
-        }
-
-        /**
          * This visitor is used to prune the graph from spurious edges using some heuristics.
          */
-        private static class PruneVisitor extends NodeVisitor<String, Node, Void> {
+        private static class PruneVisitor extends NodeVisitor<ClassSymbol, Node, Void> {
             @Override
             public void visitNode(Node node, Void arg) {
                 //do nothing
@@ -517,8 +382,7 @@
             @Override
             public void visitDependency(GraphUtils.DependencyKind dk, Node from, Node to, Void arg) {
                 //heuristic - skips dependencies that are likely to be fake
-                if (from.equals(to) ||
-                        from.depsByKind.get(Node.DependencyKind.REQUIRES).contains(to)) {
+                if (from.equals(to)) {
                     to.depsByKind.get(dk).remove(from);
                 }
             }
@@ -527,7 +391,7 @@
         /**
          * This visitor is used to retain only completion nodes with given kind.
          */
-        private class FilterVisitor extends NodeVisitor<String, Node, Void> {
+        private class FilterVisitor extends NodeVisitor<ClassSymbol, Node, Void> {
 
             CompletionNode.Kind ck;
 
@@ -571,11 +435,6 @@
         }
 
         @Override
-        public void push(AttributionKind ak, JCTree t) {
-            //do nothing
-        }
-
-        @Override
         public void pop() {
             //do nothing
         }
diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/NewDependencyCollector.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/NewDependencyCollector.java
index 10851e3..9b20471 100644
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/NewDependencyCollector.java
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/NewDependencyCollector.java
@@ -26,11 +26,13 @@
 package com.sun.tools.sjavac.comp.dependencies;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.tools.JavaFileManager.Location;
 import javax.tools.JavaFileObject;
@@ -38,7 +40,11 @@
 
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.code.Kinds.Kind;
+import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
@@ -85,7 +91,6 @@
 
         return deps.getNodes()
                    .stream()
-                   .filter(n -> n instanceof CompletionNode)
                    .map(n -> (CompletionNode) n)
                    .filter(n -> n.getClassSymbol().fullname != null)
                    .filter(n -> explicits == explicitJFOs.contains(n.getClassSymbol().classfile))
@@ -128,31 +133,66 @@
             String depPkg = Util.pkgNameOfClassName(fqDep);
 
             Map<String, Set<String>> depsForThisClass = result.get(depPkg);
-            if (depsForThisClass == null)
+            if (depsForThisClass == null) {
                 result.put(depPkg, depsForThisClass = new HashMap<>());
+            }
 
-            for (Node<?,?> depNode : cnode.getDependenciesByKind(GraphDependencies.Node.DependencyKind.REQUIRES)) {
-                boolean isCompletionNode = depNode instanceof CompletionNode;
-                if (isCompletionNode) {
-                    CompletionNode cDepNode = (CompletionNode) depNode;
-                    if (cDepNode == cnode)
-                        continue;
-                    if (cDepNode.getClassSymbol().fullname == null) // Anonymous class
-                        continue;
-                    Location depLoc = getLocationOf(cDepNode.getClassSymbol());
-                    boolean relevant = (cp  && depLoc == StandardLocation.CLASS_PATH)
-                                    || (!cp && depLoc == StandardLocation.SOURCE_PATH);
-                    if (!relevant)
-                        continue;
+            Set<String> fqDeps = depsForThisClass.get(fqDep);
+            if (fqDeps == null) {
+                depsForThisClass.put(fqDep, fqDeps = new HashSet<>());
+            }
 
-                    Set<String> fqDeps = depsForThisClass.get(fqDep);
-                    if (fqDeps == null)
-                        depsForThisClass.put(fqDep, fqDeps = new HashSet<>());
+            for (Node<?,?> depNode : getAllDependencies(cnode)) {
+                CompletionNode cDepNode = (CompletionNode) depNode;
+                // Symbol is not regarded to depend on itself.
+                if (cDepNode == cnode) {
+                    continue;
+                }
+                // Skip anonymous classes
+                if (cDepNode.getClassSymbol().fullname == null) {
+                    continue;
+                }
+                if (isSymbolRelevant(cp, cDepNode.getClassSymbol())) {
                     fqDeps.add(cDepNode.getClassSymbol().outermostClass().flatname.toString());
                 }
             }
+
+            // The completion dependency graph is not transitively closed for inheritance relations.
+            // For sjavac's purposes however, a class depends on it's super super type, so below we
+            // make sure that we include super types.
+            for (ClassSymbol cs : allSupertypes(cnode.getClassSymbol())) {
+                if (isSymbolRelevant(cp, cs)) {
+                    fqDeps.add(cs.outermostClass().flatname.toString());
+                }
+            }
+
         }
         return result;
     }
 
+    public boolean isSymbolRelevant(boolean cp, ClassSymbol cs) {
+        Location csLoc = getLocationOf(cs);
+        Location relevantLocation = cp ? StandardLocation.CLASS_PATH : StandardLocation.SOURCE_PATH;
+        return csLoc == relevantLocation;
+    }
+
+    private Set<ClassSymbol> allSupertypes(TypeSymbol t) {
+        if (t == null || !(t instanceof ClassSymbol)) {
+            return Collections.emptySet();
+        }
+        Set<ClassSymbol> result = new HashSet<>();
+        ClassSymbol cs = (ClassSymbol) t;
+        result.add(cs);
+        result.addAll(allSupertypes(cs.getSuperclass().tsym));
+        for (Type it : cs.getInterfaces()) {
+            result.addAll(allSupertypes(it.tsym));
+        }
+        return result;
+    }
+
+    private Collection<? extends Node<?, ?>> getAllDependencies(CompletionNode cnode) {
+        return Stream.of(cnode.getSupportedDependencyKinds())
+                     .flatMap(dk -> cnode.getDependenciesByKind(dk).stream())
+                     .collect(Collectors.toSet());
+    }
 }
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java
new file mode 100644
index 0000000..5a378eb
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+package jdk.internal.jshell.debug;
+
+import java.util.HashMap;
+import java.util.Map;
+import jdk.jshell.JShell;
+
+/**
+ * Used to externally control output messages for debugging the implementation
+ * of the JShell API.  This is NOT a supported interface,
+ * @author Robert Field
+ */
+public class InternalDebugControl {
+    public static final int DBG_GEN   = 0b0000001;
+    public static final int DBG_FMGR  = 0b0000010;
+    public static final int DBG_COMPA = 0b0000100;
+    public static final int DBG_DEP   = 0b0001000;
+    public static final int DBG_EVNT  = 0b0010000;
+
+    private static Map<JShell, Integer> debugMap = null;
+
+    public static void setDebugFlags(JShell state, int flags) {
+        if (debugMap == null) {
+            debugMap = new HashMap<>();
+        }
+        debugMap.put(state, flags);
+    }
+
+    public static boolean debugEnabled(JShell state, int flag) {
+        if (debugMap == null) {
+            return false;
+        }
+        Integer flags = debugMap.get(state);
+        if (flags == null) {
+            return false;
+        }
+        return (flags & flag) != 0;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java
new file mode 100644
index 0000000..bbebbfe
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.remote;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Socket;
+
+import java.util.ArrayList;
+import java.util.List;
+import static jdk.internal.jshell.remote.RemoteCodes.*;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * The remote agent runs in the execution process (separate from the main JShell
+ * process.  This agent loads code over a socket from the main JShell process,
+ * executes the code, and other misc,
+ * @author Robert Field
+ */
+class RemoteAgent {
+
+    private final RemoteClassLoader loader = new RemoteClassLoader();
+    private final Map<String, Class<?>> klasses = new TreeMap<>();
+
+    public static void main(String[] args) throws Exception {
+        String loopBack = null;
+        Socket socket = new Socket(loopBack, Integer.parseInt(args[0]));
+        (new RemoteAgent()).commandLoop(socket);
+    }
+
+    void commandLoop(Socket socket) throws IOException {
+        // in before out -- so we don't hang the controlling process
+        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
+        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
+        while (true) {
+            int cmd = in.readInt();
+            switch (cmd) {
+                case CMD_EXIT:
+                    // Terminate this process
+                    return;
+                case CMD_LOAD:
+                    // Load a generated class file over the wire
+                    try {
+                        int count = in.readInt();
+                        List<String> names = new ArrayList<>(count);
+                        for (int i = 0; i < count; ++i) {
+                            String name = in.readUTF();
+                            byte[] kb = (byte[]) in.readObject();
+                            loader.delare(name, kb);
+                            names.add(name);
+                        }
+                        for (String name : names) {
+                            Class<?> klass = loader.loadClass(name);
+                            klasses.put(name, klass);
+                            // Get class loaded to the point of, at least, preparation
+                            klass.getDeclaredMethods();
+                        }
+                        out.writeInt(RESULT_SUCCESS);
+                        out.flush();
+                    } catch (IOException | ClassNotFoundException | ClassCastException ex) {
+                        debug("*** Load failure: %s\n", ex);
+                        out.writeInt(RESULT_FAIL);
+                        out.writeUTF(ex.toString());
+                        out.flush();
+                    }
+                    break;
+                case CMD_INVOKE: {
+                    // Invoke executable entry point in loaded code
+                    String name = in.readUTF();
+                    Class<?> klass = klasses.get(name);
+                    if (klass == null) {
+                        debug("*** Invoke failure: no such class loaded %s\n", name);
+                        out.writeInt(RESULT_FAIL);
+                        out.writeUTF("no such class loaded: " + name);
+                        out.flush();
+                        break;
+                    }
+                    Method doitMethod;
+                    try {
+                        doitMethod = klass.getDeclaredMethod(DOIT_METHOD_NAME, new Class<?>[0]);
+                        doitMethod.setAccessible(true);
+                        Object res;
+                        try {
+                            clientCodeEnter();
+                            res = doitMethod.invoke(null, new Object[0]);
+                        } catch (InvocationTargetException ex) {
+                            if (ex.getCause() instanceof StopExecutionException) {
+                                expectingStop = false;
+                                throw (StopExecutionException) ex.getCause();
+                            }
+                            throw ex;
+                        } catch (StopExecutionException ex) {
+                            expectingStop = false;
+                            throw ex;
+                        } finally {
+                            clientCodeLeave();
+                        }
+                        out.writeInt(RESULT_SUCCESS);
+                        out.writeUTF(valueString(res));
+                        out.flush();
+                    } catch (InvocationTargetException ex) {
+                        Throwable cause = ex.getCause();
+                        StackTraceElement[] elems = cause.getStackTrace();
+                        if (cause instanceof RemoteResolutionException) {
+                            out.writeInt(RESULT_CORRALLED);
+                            out.writeInt(((RemoteResolutionException) cause).id);
+                        } else {
+                            out.writeInt(RESULT_EXCEPTION);
+                            out.writeUTF(cause.getClass().getName());
+                            out.writeUTF(cause.getMessage() == null ? "<none>" : cause.getMessage());
+                        }
+                        out.writeInt(elems.length);
+                        for (StackTraceElement ste : elems) {
+                            out.writeUTF(ste.getClassName());
+                            out.writeUTF(ste.getMethodName());
+                            out.writeUTF(ste.getFileName() == null ? "<none>" : ste.getFileName());
+                            out.writeInt(ste.getLineNumber());
+                        }
+                        out.flush();
+                    } catch (NoSuchMethodException | IllegalAccessException ex) {
+                        debug("*** Invoke failure: %s -- %s\n", ex, ex.getCause());
+                        out.writeInt(RESULT_FAIL);
+                        out.writeUTF(ex.toString());
+                        out.flush();
+                    } catch (StopExecutionException ex) {
+                        try {
+                            out.writeInt(RESULT_KILLED);
+                            out.flush();
+                        } catch (IOException err) {
+                            debug("*** Error writing killed result: %s -- %s\n", ex, ex.getCause());
+                        }
+                    }
+                    System.out.flush();
+                    break;
+                }
+                case CMD_VARVALUE: {
+                    // Retrieve a variable value
+                    String classname = in.readUTF();
+                    String varname = in.readUTF();
+                    Class<?> klass = klasses.get(classname);
+                    if (klass == null) {
+                        debug("*** Var value failure: no such class loaded %s\n", classname);
+                        out.writeInt(RESULT_FAIL);
+                        out.writeUTF("no such class loaded: " + classname);
+                        out.flush();
+                        break;
+                    }
+                    try {
+                        Field var = klass.getDeclaredField(varname);
+                        var.setAccessible(true);
+                        Object res = var.get(null);
+                        out.writeInt(RESULT_SUCCESS);
+                        out.writeUTF(valueString(res));
+                        out.flush();
+                    } catch (Exception ex) {
+                        debug("*** Var value failure: no such field %s.%s\n", classname, varname);
+                        out.writeInt(RESULT_FAIL);
+                        out.writeUTF("no such field loaded: " + varname + " in class: " + classname);
+                        out.flush();
+                    }
+                    break;
+                }
+                case CMD_CLASSPATH: {
+                    // Append to the claspath
+                    String cp = in.readUTF();
+                    for (String path : cp.split(File.pathSeparator)) {
+                        loader.addURL(new File(path).toURI().toURL());
+                    }
+                    out.writeInt(RESULT_SUCCESS);
+                    out.flush();
+                    break;
+                }
+                default:
+                    debug("*** Bad command code: %d\n", cmd);
+                    break;
+            }
+        }
+    }
+
+    // These three variables are used by the main JShell process in interrupting
+    // the running process.  Access is via JDI, so the reference is not visible
+    // to code inspection.
+    private boolean inClientCode; // Queried by the main process
+    private boolean expectingStop; // Set by the main process
+
+    // thrown by the main process via JDI:
+    private final StopExecutionException stopException = new StopExecutionException();
+
+    @SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+    private class StopExecutionException extends ThreadDeath {
+        @Override public synchronized Throwable fillInStackTrace() {
+            return this;
+        }
+    }
+
+    void clientCodeEnter() {
+        expectingStop = false;
+        inClientCode = true;
+    }
+
+    void clientCodeLeave() {
+        inClientCode = false;
+        while (expectingStop) {
+            try {
+                Thread.sleep(0);
+            } catch (InterruptedException ex) {
+                debug("*** Sleep interrupted while waiting for stop exception: %s\n", ex);
+            }
+        }
+    }
+
+    private void debug(String format, Object... args) {
+        System.err.printf("REMOTE: "+format, args);
+    }
+
+    static String valueString(Object value) {
+        if (value == null) {
+            return "null";
+        } else if (value instanceof String) {
+            return "\"" + expunge((String)value) + "\"";
+        } else if (value instanceof Character) {
+            return "'" + value + "'";
+        } else {
+            return expunge(value.toString());
+        }
+    }
+
+    static String expunge(String s) {
+        StringBuilder sb = new StringBuilder();
+        for (String comp : prefixPattern.split(s)) {
+            sb.append(comp);
+        }
+        return sb.toString();
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteClassLoader.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteClassLoader.java
new file mode 100644
index 0000000..e6cf4ce
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteClassLoader.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.remote;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.CodeSource;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Class loader wrapper which caches class files by name until requested.
+ * @author Robert Field
+ */
+class RemoteClassLoader extends URLClassLoader {
+
+    private final Map<String, byte[]> classObjects = new TreeMap<>();
+
+    RemoteClassLoader() {
+        super(new URL[0]);
+    }
+
+    void delare(String name, byte[] bytes) {
+        classObjects.put(name, bytes);
+    }
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        byte[] b = classObjects.get(name);
+        if (b == null) {
+            return super.findClass(name);
+        }
+        return super.defineClass(name, b, 0, b.length, (CodeSource) null);
+    }
+
+    @Override
+    public void addURL(URL url) {
+        super.addURL(url);
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java
new file mode 100644
index 0000000..0f26b79
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteCodes.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package jdk.internal.jshell.remote;
+
+import java.util.regex.Pattern;
+
+/**
+ * Communication constants shared between the main process and the remote
+ * execution process
+ * @author Robert Field
+ */
+public class RemoteCodes {
+    // Command codes
+    public static final int CMD_EXIT       = 0;
+    public static final int CMD_LOAD       = 1;
+    public static final int CMD_INVOKE     = 3;
+    public static final int CMD_CLASSPATH  = 4;
+    public static final int CMD_VARVALUE   = 5;
+
+    // Return result codes
+    public static final int RESULT_SUCCESS   = 100;
+    public static final int RESULT_FAIL      = 101;
+    public static final int RESULT_EXCEPTION = 102;
+    public static final int RESULT_CORRALLED = 103;
+    public static final int RESULT_KILLED    = 104;
+
+    public static final String DOIT_METHOD_NAME = "do_it$";
+    public static final String replClass = "\\$REPL(?<num>\\d+)[A-Z]*";
+    public static final Pattern prefixPattern = Pattern.compile("(REPL\\.)?" + replClass + "[\\$\\.]?");
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteResolutionException.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteResolutionException.java
new file mode 100644
index 0000000..8026979
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteResolutionException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.remote;
+
+/**
+ * The exception thrown on the remote side upon executing a
+ * {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED}
+ * user method. This exception is not seen by the end user nor through the API.
+ * @author Robert Field
+ */
+@SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+public class RemoteResolutionException extends RuntimeException {
+
+    final int id;
+
+    /**
+     * The throw of this exception is generated into the body of a
+     * {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED}
+     * method.
+     * @param id An internal identifier of the specific method
+     */
+    public RemoteResolutionException(int id) {
+        super("RemoteResolutionException");
+        this.id = id;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
new file mode 100644
index 0000000..ebc11be
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.tool;
+
+import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
+import jdk.jshell.SourceCodeAnalysis.Suggestion;
+
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Supplier;
+
+import jdk.internal.jline.NoInterruptUnixTerminal;
+import jdk.internal.jline.Terminal;
+import jdk.internal.jline.TerminalFactory;
+import jdk.internal.jline.WindowsTerminal;
+import jdk.internal.jline.console.ConsoleReader;
+import jdk.internal.jline.console.KeyMap;
+import jdk.internal.jline.console.UserInterruptException;
+import jdk.internal.jline.console.completer.Completer;
+import jdk.internal.jshell.tool.StopDetectingInputStream.State;
+
+class ConsoleIOContext extends IOContext {
+
+    final JShellTool repl;
+    final StopDetectingInputStream input;
+    final ConsoleReader in;
+    final EditingHistory history;
+
+    String prefix = "";
+
+    ConsoleIOContext(JShellTool repl, InputStream cmdin, PrintStream cmdout) throws Exception {
+        this.repl = repl;
+        this.input = new StopDetectingInputStream(() -> repl.state.stop(), ex -> repl.hard("Error on input: %s", ex));
+        Terminal term;
+        if (System.getProperty("os.name").toLowerCase(Locale.US).contains(TerminalFactory.WINDOWS)) {
+            term = new JShellWindowsTerminal(input);
+        } else {
+            term = new JShellUnixTerminal(input);
+        }
+        term.init();
+        in = new ConsoleReader(cmdin, cmdout, term);
+        in.setExpandEvents(false);
+        in.setHandleUserInterrupt(true);
+        in.setHistory(history = new EditingHistory(JShellTool.PREFS) {
+            @Override protected CompletionInfo analyzeCompletion(String input) {
+                return repl.analysis.analyzeCompletion(input);
+            }
+        });
+        in.setBellEnabled(true);
+        in.addCompleter(new Completer() {
+            private String lastTest;
+            private int lastCursor;
+            private boolean allowSmart = false;
+            @Override public int complete(String test, int cursor, List<CharSequence> result) {
+                int[] anchor = new int[] {-1};
+                List<Suggestion> suggestions;
+                if (prefix.isEmpty() && test.trim().startsWith("/")) {
+                    suggestions = repl.commandCompletionSuggestions(test, cursor, anchor);
+                } else {
+                    int prefixLength = prefix.length();
+                    suggestions = repl.analysis.completionSuggestions(prefix + test, cursor + prefixLength, anchor);
+                    anchor[0] -= prefixLength;
+                }
+                if (!Objects.equals(lastTest, test) || lastCursor != cursor)
+                    allowSmart = true;
+
+                boolean smart = allowSmart &&
+                                suggestions.stream()
+                                           .anyMatch(s -> s.isSmart);
+
+                lastTest = test;
+                lastCursor = cursor;
+                allowSmart = !allowSmart;
+
+                suggestions.stream()
+                           .filter(s -> !smart || s.isSmart)
+                           .map(s -> s.continuation)
+                           .forEach(result::add);
+
+                boolean onlySmart = suggestions.stream()
+                                               .allMatch(s -> s.isSmart);
+
+                if (smart && !onlySmart) {
+                    Optional<String> prefix =
+                            suggestions.stream()
+                                       .map(s -> s.continuation)
+                                       .reduce(ConsoleIOContext::commonPrefix);
+
+                    String prefixStr = prefix.orElse("").substring(cursor - anchor[0]);
+                    try {
+                        in.putString(prefixStr);
+                        cursor += prefixStr.length();
+                    } catch (IOException ex) {
+                        throw new IllegalStateException(ex);
+                    }
+                    result.add("<press tab to see more>");
+                    return cursor; //anchor should not be used.
+                }
+
+                if (result.isEmpty()) {
+                    try {
+                        //provide "empty completion" feedback
+                        //XXX: this only works correctly when there is only one Completer:
+                        in.beep();
+                    } catch (IOException ex) {
+                        throw new UncheckedIOException(ex);
+                    }
+                }
+
+                return anchor[0];
+            }
+        });
+        bind(DOCUMENTATION_SHORTCUT, (ActionListener) evt -> documentation(repl));
+        bind(CTRL_UP, (ActionListener) evt -> moveHistoryToSnippet(((EditingHistory) in.getHistory())::previousSnippet));
+        bind(CTRL_DOWN, (ActionListener) evt -> moveHistoryToSnippet(((EditingHistory) in.getHistory())::nextSnippet));
+    }
+
+    @Override
+    public String readLine(String prompt, String prefix) throws IOException, InputInterruptedException {
+        this.prefix = prefix;
+        try {
+            return in.readLine(prompt);
+        } catch (UserInterruptException ex) {
+            throw (InputInterruptedException) new InputInterruptedException().initCause(ex);
+        }
+    }
+
+    @Override
+    public boolean interactiveOutput() {
+        return true;
+    }
+
+    @Override
+    public Iterable<String> currentSessionHistory() {
+        return history.currentSessionEntries();
+    }
+
+    @Override
+    public void close() throws IOException {
+        history.save();
+        in.shutdown();
+        try {
+            in.getTerminal().restore();
+        } catch (Exception ex) {
+            throw new IOException(ex);
+        }
+    }
+
+    private void moveHistoryToSnippet(Supplier<Boolean> action) {
+        if (!action.get()) {
+            try {
+                in.beep();
+            } catch (IOException ex) {
+                throw new IllegalStateException(ex);
+            }
+        } else {
+            try {
+                //could use:
+                //in.resetPromptLine(in.getPrompt(), in.getHistory().current().toString(), -1);
+                //but that would mean more re-writing on the screen, (and prints an additional
+                //empty line), so using setBuffer directly:
+                Method setBuffer = in.getClass().getDeclaredMethod("setBuffer", String.class);
+
+                setBuffer.setAccessible(true);
+                setBuffer.invoke(in, in.getHistory().current().toString());
+                in.flush();
+            } catch (ReflectiveOperationException | IOException ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+    }
+
+    private void bind(String shortcut, Object action) {
+        KeyMap km = in.getKeys();
+        for (int i = 0; i < shortcut.length(); i++) {
+            Object value = km.getBound(Character.toString(shortcut.charAt(i)));
+            if (value instanceof KeyMap) {
+                km = (KeyMap) value;
+            } else {
+                km.bind(shortcut.substring(i), action);
+            }
+        }
+    }
+
+    private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
+    private static final String CTRL_UP = "\033\133\061\073\065\101"; //Ctrl-UP
+    private static final String CTRL_DOWN = "\033\133\061\073\065\102"; //Ctrl-DOWN
+
+    private void documentation(JShellTool repl) {
+        String buffer = in.getCursorBuffer().buffer.toString();
+        int cursor = in.getCursorBuffer().cursor;
+        String doc;
+        if (prefix.isEmpty() && buffer.trim().startsWith("/")) {
+            doc = repl.commandDocumentation(buffer, cursor);
+        } else {
+            doc = repl.analysis.documentation(prefix + buffer, cursor + prefix.length());
+        }
+
+        try {
+            if (doc != null) {
+                in.println();
+                in.println(doc);
+                in.redrawLine();
+                in.flush();
+            } else {
+                in.beep();
+            }
+        } catch (IOException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    private static String commonPrefix(String str1, String str2) {
+        for (int i = 0; i < str2.length(); i++) {
+            if (!str1.startsWith(str2.substring(0, i + 1))) {
+                return str2.substring(0, i);
+            }
+        }
+
+        return str2;
+    }
+
+    @Override
+    public boolean terminalEditorRunning() {
+        Terminal terminal = in.getTerminal();
+        if (terminal instanceof JShellUnixTerminal)
+            return ((JShellUnixTerminal) terminal).isRaw();
+        return false;
+    }
+
+    @Override
+    public void suspend() {
+        try {
+            in.getTerminal().restore();
+        } catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    @Override
+    public void resume() {
+        try {
+            in.getTerminal().init();
+        } catch (Exception ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    public void beforeUserCode() {
+        input.setState(State.BUFFER);
+    }
+
+    public void afterUserCode() {
+        input.setState(State.WAIT);
+    }
+
+    @Override
+    public void replaceLastHistoryEntry(String source) {
+        history.fullHistoryReplace(source);
+    }
+
+    private static final class JShellUnixTerminal extends NoInterruptUnixTerminal {
+
+        private final StopDetectingInputStream input;
+
+        public JShellUnixTerminal(StopDetectingInputStream input) throws Exception {
+            this.input = input;
+        }
+
+        public boolean isRaw() {
+            try {
+                return getSettings().get("-a").contains("-icanon");
+            } catch (IOException | InterruptedException ex) {
+                return false;
+            }
+        }
+
+        @Override
+        public InputStream wrapInIfNeeded(InputStream in) throws IOException {
+            return input.setInputStream(super.wrapInIfNeeded(in));
+        }
+
+        @Override
+        public void disableInterruptCharacter() {
+        }
+
+        @Override
+        public void enableInterruptCharacter() {
+        }
+
+    }
+
+    private static final class JShellWindowsTerminal extends WindowsTerminal {
+
+        private final StopDetectingInputStream input;
+
+        public JShellWindowsTerminal(StopDetectingInputStream input) throws Exception {
+            this.input = input;
+        }
+
+        @Override
+        public void init() throws Exception {
+            super.init();
+            setAnsiSupported(false);
+        }
+
+        @Override
+        public InputStream wrapInIfNeeded(InputStream in) throws IOException {
+            return input.setInputStream(super.wrapInIfNeeded(in));
+        }
+
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditPad.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditPad.java
new file mode 100644
index 0000000..2b25243
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditPad.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.tool;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Consumer;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+/**
+ * A minimal Swing editor as a fallback when the user does not specify an
+ * external editor.
+ */
+@SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+public class EditPad extends JFrame implements Runnable {
+    private final Consumer<String> errorHandler; // For possible future error handling
+    private final String initialText;
+    private final CountDownLatch closeLock;
+    private final Consumer<String> saveHandler;
+
+    EditPad(Consumer<String> errorHandler, String initialText,
+            CountDownLatch closeLock, Consumer<String> saveHandler) {
+        super("JShell Edit Pad");
+        this.errorHandler = errorHandler;
+        this.initialText = initialText;
+        this.closeLock = closeLock;
+        this.saveHandler = saveHandler;
+    }
+
+    @Override
+    public void run() {
+        addWindowListener(new WindowAdapter() {
+            @Override
+            public void windowClosing(WindowEvent e) {
+                EditPad.this.dispose();
+                closeLock.countDown();
+            }
+        });
+        setLocationRelativeTo(null);
+        setLayout(new BorderLayout());
+        JTextArea textArea = new JTextArea(initialText);
+        add(new JScrollPane(textArea), BorderLayout.CENTER);
+        add(buttons(textArea), BorderLayout.SOUTH);
+
+        setSize(800, 600);
+        setVisible(true);
+    }
+
+    private JPanel buttons(JTextArea textArea) {
+        FlowLayout flow = new FlowLayout();
+        flow.setHgap(35);
+        JPanel buttons = new JPanel(flow);
+        JButton cancel = new JButton("Cancel");
+        cancel.setMnemonic(KeyEvent.VK_C);
+        JButton accept = new JButton("Accept");
+        accept.setMnemonic(KeyEvent.VK_A);
+        JButton exit = new JButton("Exit");
+        exit.setMnemonic(KeyEvent.VK_X);
+        buttons.add(cancel);
+        buttons.add(accept);
+        buttons.add(exit);
+
+        cancel.addActionListener(e -> {
+            close();
+        });
+        accept.addActionListener(e -> {
+            saveHandler.accept(textArea.getText());
+        });
+        exit.addActionListener(e -> {
+            saveHandler.accept(textArea.getText());
+            close();
+        });
+
+        return buttons;
+    }
+
+    private void close() {
+        setVisible(false);
+        dispose();
+        closeLock.countDown();
+    }
+
+    public static void edit(Consumer<String> errorHandler, String initialText,
+            Consumer<String> saveHandler) {
+        CountDownLatch closeLock = new CountDownLatch(1);
+        SwingUtilities.invokeLater(
+                new EditPad(errorHandler, initialText, closeLock, saveHandler));
+        do {
+            try {
+                closeLock.await();
+                break;
+            } catch (InterruptedException ex) {
+                // ignore and loop
+            }
+        } while (true);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditingHistory.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditingHistory.java
new file mode 100644
index 0000000..ae13265
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/EditingHistory.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.jshell.tool;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.internal.jline.console.history.History;
+import jdk.internal.jline.console.history.History.Entry;
+import jdk.internal.jline.console.history.MemoryHistory;
+import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
+
+/*Public for tests (HistoryTest).
+ */
+public abstract class EditingHistory implements History {
+
+    private final Preferences prefs;
+    private final History fullHistory;
+    private History currentDelegate;
+
+    protected EditingHistory(Preferences prefs) {
+        this.prefs = prefs;
+        this.fullHistory = new MemoryHistory();
+        this.currentDelegate = fullHistory;
+        load();
+    }
+
+    @Override
+    public int size() {
+        return currentDelegate.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return currentDelegate.isEmpty();
+    }
+
+    @Override
+    public int index() {
+        return currentDelegate.index();
+    }
+
+    @Override
+    public void clear() {
+        if (currentDelegate != fullHistory)
+            throw new IllegalStateException("narrowed");
+        currentDelegate.clear();
+    }
+
+    @Override
+    public CharSequence get(int index) {
+        return currentDelegate.get(index);
+    }
+
+    @Override
+    public void add(CharSequence line) {
+        NarrowingHistoryLine currentLine = null;
+        int origIndex = fullHistory.index();
+        int fullSize;
+        try {
+            fullHistory.moveToEnd();
+            fullSize = fullHistory.index();
+            if (currentDelegate == fullHistory) {
+                if (origIndex < fullHistory.index()) {
+                    for (Entry entry : fullHistory) {
+                        if (!(entry.value() instanceof NarrowingHistoryLine))
+                            continue;
+                        int[] cluster = ((NarrowingHistoryLine) entry.value()).span;
+                        if (cluster[0] == origIndex && cluster[1] > cluster[0]) {
+                            currentDelegate = new MemoryHistory();
+                            for (int i = cluster[0]; i <= cluster[1]; i++) {
+                                currentDelegate.add(fullHistory.get(i));
+                            }
+                        }
+                    }
+                }
+            }
+            fullHistory.moveToEnd();
+            while (fullHistory.previous()) {
+                CharSequence c = fullHistory.current();
+                if (c instanceof NarrowingHistoryLine) {
+                    currentLine = (NarrowingHistoryLine) c;
+                    break;
+                }
+            }
+        } finally {
+            fullHistory.moveTo(origIndex);
+        }
+        if (currentLine == null || currentLine.span[1] != (-1)) {
+            line = currentLine = new NarrowingHistoryLine(line, fullSize);
+        }
+        StringBuilder complete = new StringBuilder();
+        for (int i = currentLine.span[0]; i < fullSize; i++) {
+            complete.append(fullHistory.get(i));
+        }
+        complete.append(line);
+        if (analyzeCompletion(complete.toString()).completeness.isComplete) {
+            currentLine.span[1] = fullSize; //TODO: +1?
+            currentDelegate = fullHistory;
+        }
+        fullHistory.add(line);
+    }
+
+    protected abstract CompletionInfo analyzeCompletion(String input);
+
+    @Override
+    public void set(int index, CharSequence item) {
+        if (currentDelegate != fullHistory)
+            throw new IllegalStateException("narrowed");
+        currentDelegate.set(index, item);
+    }
+
+    @Override
+    public CharSequence remove(int i) {
+        if (currentDelegate != fullHistory)
+            throw new IllegalStateException("narrowed");
+        return currentDelegate.remove(i);
+    }
+
+    @Override
+    public CharSequence removeFirst() {
+        if (currentDelegate != fullHistory)
+            throw new IllegalStateException("narrowed");
+        return currentDelegate.removeFirst();
+    }
+
+    @Override
+    public CharSequence removeLast() {
+        if (currentDelegate != fullHistory)
+            throw new IllegalStateException("narrowed");
+        return currentDelegate.removeLast();
+    }
+
+    @Override
+    public void replace(CharSequence item) {
+        if (currentDelegate != fullHistory)
+            throw new IllegalStateException("narrowed");
+        currentDelegate.replace(item);
+    }
+
+    @Override
+    public ListIterator<Entry> entries(int index) {
+        return currentDelegate.entries(index);
+    }
+
+    @Override
+    public ListIterator<Entry> entries() {
+        return currentDelegate.entries();
+    }
+
+    @Override
+    public Iterator<Entry> iterator() {
+        return currentDelegate.iterator();
+    }
+
+    @Override
+    public CharSequence current() {
+        return currentDelegate.current();
+    }
+
+    @Override
+    public boolean previous() {
+        return currentDelegate.previous();
+    }
+
+    @Override
+    public boolean next() {
+        return currentDelegate.next();
+    }
+
+    @Override
+    public boolean moveToFirst() {
+        return currentDelegate.moveToFirst();
+    }
+
+    @Override
+    public boolean moveToLast() {
+        return currentDelegate.moveToLast();
+    }
+
+    @Override
+    public boolean moveTo(int index) {
+        return currentDelegate.moveTo(index);
+    }
+
+    @Override
+    public void moveToEnd() {
+        currentDelegate.moveToEnd();
+    }
+
+    public boolean previousSnippet() {
+        for (int i = index() - 1; i >= 0; i--) {
+            if (get(i) instanceof NarrowingHistoryLine) {
+                moveTo(i);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean nextSnippet() {
+        for (int i = index() + 1; i < size(); i++) {
+            if (get(i) instanceof NarrowingHistoryLine) {
+                moveTo(i);
+                return true;
+            }
+        }
+
+        if (index() < size()) {
+            moveToEnd();
+            return true;
+        }
+
+        return false;
+    }
+
+    private static final String HISTORY_LINE_PREFIX = "HISTORY_LINE_";
+    private static final String HISTORY_SNIPPET_START = "HISTORY_SNIPPET";
+
+    public final void load() {
+        try {
+            Set<Integer> snippetsStart = new HashSet<>();
+            for (String start : prefs.get(HISTORY_SNIPPET_START, "").split(";")) {
+                if (!start.isEmpty())
+                    snippetsStart.add(Integer.parseInt(start));
+            }
+            List<String> keys = Stream.of(prefs.keys()).sorted().collect(Collectors.toList());
+            NarrowingHistoryLine currentHistoryLine = null;
+            int currentLine = 0;
+            for (String key : keys) {
+                if (!key.startsWith(HISTORY_LINE_PREFIX))
+                    continue;
+                CharSequence line = prefs.get(key, "");
+                if (snippetsStart.contains(currentLine)) {
+                    class PersistentNarrowingHistoryLine extends NarrowingHistoryLine implements PersistentEntryMarker {
+                        public PersistentNarrowingHistoryLine(CharSequence delegate, int start) {
+                            super(delegate, start);
+                        }
+                    }
+                    line = currentHistoryLine = new PersistentNarrowingHistoryLine(line, currentLine);
+                } else {
+                    class PersistentLine implements CharSequence, PersistentEntryMarker {
+                        private final CharSequence delegate;
+                        public PersistentLine(CharSequence delegate) {
+                            this.delegate = delegate;
+                        }
+                        @Override public int length() {
+                            return delegate.length();
+                        }
+                        @Override public char charAt(int index) {
+                            return delegate.charAt(index);
+                        }
+                        @Override public CharSequence subSequence(int start, int end) {
+                            return delegate.subSequence(start, end);
+                        }
+                        @Override public String toString() {
+                            return delegate.toString();
+                        }
+                    }
+                    line = new PersistentLine(line);
+                }
+                if (currentHistoryLine != null)
+                    currentHistoryLine.span[1] = currentLine;
+                currentLine++;
+                fullHistory.add(line);
+            }
+            currentLine = 0;
+        } catch (BackingStoreException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    public void save() {
+        try {
+            for (String key : prefs.keys()) {
+                if (key.startsWith(HISTORY_LINE_PREFIX))
+                    prefs.remove(key);
+            }
+            Iterator<Entry> entries = fullHistory.iterator();
+            if (entries.hasNext()) {
+                int len = (int) Math.ceil(Math.log10(fullHistory.size()+1));
+                String format = HISTORY_LINE_PREFIX + "%0" + len + "d";
+                StringBuilder snippetStarts = new StringBuilder();
+                String snippetStartDelimiter = "";
+                while (entries.hasNext()) {
+                    Entry entry = entries.next();
+                    prefs.put(String.format(format, entry.index()), entry.value().toString());
+                    if (entry.value() instanceof NarrowingHistoryLine) {
+                        snippetStarts.append(snippetStartDelimiter);
+                        snippetStarts.append(entry.index());
+                        snippetStartDelimiter = ";";
+                    }
+                }
+                prefs.put(HISTORY_SNIPPET_START, snippetStarts.toString());
+            }
+        } catch (BackingStoreException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
+
+    public List<String> currentSessionEntries() {
+        List<String> result = new ArrayList<>();
+
+        for (Entry e : fullHistory) {
+            if (!(e.value() instanceof PersistentEntryMarker)) {
+                result.add(e.value().toString());
+            }
+        }
+
+        return result;
+    }
+
+    void fullHistoryReplace(String source) {
+        fullHistory.replace(source);
+    }
+
+    private class NarrowingHistoryLine implements CharSequence {
+        private final CharSequence delegate;
+        private final int[] span;
+
+        public NarrowingHistoryLine(CharSequence delegate, int start) {
+            this.delegate = delegate;
+            this.span = new int[] {start, -1};
+        }
+
+        @Override
+        public int length() {
+            return delegate.length();
+        }
+
+        @Override
+        public char charAt(int index) {
+            return delegate.charAt(index);
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return delegate.subSequence(start, end);
+        }
+
+        @Override
+        public String toString() {
+            return delegate.toString();
+        }
+
+    }
+
+    private interface PersistentEntryMarker {}
+}
+
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java
new file mode 100644
index 0000000..e20db94
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.tool;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.ClosedWatchServiceException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
+import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
+
+/**
+ * Wrapper for controlling an external editor.
+ */
+public class ExternalEditor {
+    private final Consumer<String> errorHandler;
+    private final Consumer<String> saveHandler;
+    private final IOContext input;
+
+    private WatchService watcher;
+    private Thread watchedThread;
+    private Path dir;
+    private Path tmpfile;
+
+    ExternalEditor(Consumer<String> errorHandler, Consumer<String> saveHandler, IOContext input) {
+        this.errorHandler = errorHandler;
+        this.saveHandler = saveHandler;
+        this.input = input;
+    }
+
+    private void edit(String cmd, String initialText) {
+        try {
+            setupWatch(initialText);
+            launch(cmd);
+        } catch (IOException ex) {
+            errorHandler.accept(ex.getMessage());
+        }
+    }
+
+    /**
+     * Creates a WatchService and registers the given directory
+     */
+    private void setupWatch(String initialText) throws IOException {
+        this.watcher = FileSystems.getDefault().newWatchService();
+        this.dir = Files.createTempDirectory("REPL");
+        this.tmpfile = Files.createTempFile(dir, null, ".repl");
+        Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8")));
+        dir.register(watcher,
+                ENTRY_CREATE,
+                ENTRY_DELETE,
+                ENTRY_MODIFY);
+        watchedThread = new Thread(() -> {
+            for (;;) {
+                WatchKey key;
+                try {
+                    key = watcher.take();
+                } catch (ClosedWatchServiceException ex) {
+                    break;
+                } catch (InterruptedException ex) {
+                    continue; // tolerate an intrupt
+                }
+
+                if (!key.pollEvents().isEmpty()) {
+                    if (!input.terminalEditorRunning()) {
+                        saveFile();
+                    }
+                }
+
+                boolean valid = key.reset();
+                if (!valid) {
+                    errorHandler.accept("Invalid key");
+                    break;
+                }
+            }
+        });
+        watchedThread.start();
+    }
+
+    private void launch(String cmd) throws IOException {
+        ProcessBuilder pb = new ProcessBuilder(cmd, tmpfile.toString());
+        pb = pb.inheritIO();
+
+        try {
+            input.suspend();
+            Process process = pb.start();
+            process.waitFor();
+        } catch (IOException ex) {
+            errorHandler.accept("process IO failure: " + ex.getMessage());
+        } catch (InterruptedException ex) {
+            errorHandler.accept("process interrupt: " + ex.getMessage());
+        } finally {
+            try {
+                watcher.close();
+                watchedThread.join(); //so that saveFile() is finished.
+                saveFile();
+            } catch (InterruptedException ex) {
+                errorHandler.accept("process interrupt: " + ex.getMessage());
+            } finally {
+                input.resume();
+            }
+        }
+    }
+
+    private void saveFile() {
+        try {
+            saveHandler.accept(Files.lines(tmpfile).collect(Collectors.joining("\n", "", "\n")));
+        } catch (IOException ex) {
+            errorHandler.accept("Failure in read edit file: " + ex.getMessage());
+        }
+    }
+
+    static void edit(String cmd, Consumer<String> errorHandler, String initialText,
+            Consumer<String> saveHandler, IOContext input) {
+        ExternalEditor ed = new ExternalEditor(errorHandler,  saveHandler, input);
+        ed.edit(cmd, initialText);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java
new file mode 100644
index 0000000..8f8606f
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.tool;
+
+import java.io.IOException;
+
+/**
+ * Interface for defining user interaction with the shell.
+ * @author Robert Field
+ */
+abstract class IOContext implements AutoCloseable {
+
+    @Override
+    public abstract void close() throws IOException;
+
+    public abstract String readLine(String prompt, String prefix) throws IOException, InputInterruptedException;
+
+    public abstract boolean interactiveOutput();
+
+    public abstract Iterable<String> currentSessionHistory();
+
+    public abstract  boolean terminalEditorRunning();
+
+    public abstract void suspend();
+
+    public abstract void resume();
+
+    public abstract void beforeUserCode();
+
+    public abstract void afterUserCode();
+
+    public abstract void replaceLastHistoryEntry(String source);
+
+    class InputInterruptedException extends Exception {
+        private static final long serialVersionUID = 1L;
+    }
+}
+
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
new file mode 100644
index 0000000..9bc5567
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java
@@ -0,0 +1,1804 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.jshell.tool;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.prefs.Preferences;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import jdk.internal.jshell.debug.InternalDebugControl;
+import jdk.internal.jshell.tool.IOContext.InputInterruptedException;
+import jdk.jshell.Diag;
+import jdk.jshell.EvalException;
+import jdk.jshell.JShell;
+import jdk.jshell.Snippet;
+import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.MethodSnippet;
+import jdk.jshell.PersistentSnippet;
+import jdk.jshell.VarSnippet;
+import jdk.jshell.ExpressionSnippet;
+import jdk.jshell.Snippet.Status;
+import jdk.jshell.SourceCodeAnalysis;
+import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
+import jdk.jshell.SourceCodeAnalysis.Suggestion;
+import jdk.jshell.SnippetEvent;
+import jdk.jshell.UnresolvedReferenceException;
+import jdk.jshell.Snippet.SubKind;
+import jdk.jshell.JShell.Subscription;
+
+import static java.nio.file.StandardOpenOption.CREATE;
+import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
+import static java.nio.file.StandardOpenOption.WRITE;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import static java.util.stream.Collectors.toList;
+
+/**
+ * Command line REPL tool for Java using the JShell API.
+ * @author Robert Field
+ */
+public class JShellTool {
+
+    private static final Pattern LINEBREAK = Pattern.compile("\\R");
+    private static final Pattern HISTORY_ALL_FILENAME = Pattern.compile(
+            "((?<cmd>(all|history))(\\z|\\p{javaWhitespace}+))?(?<filename>.*)");
+
+    final InputStream cmdin;
+    final PrintStream cmdout;
+    final PrintStream cmderr;
+    final PrintStream console;
+    final InputStream userin;
+    final PrintStream userout;
+    final PrintStream usererr;
+
+    /**
+     * The constructor for the tool (used by tool launch via main and by test
+     * harnesses to capture ins and outs.
+     * @param cmdin command line input -- snippets and commands
+     * @param cmdout command line output, feedback including errors
+     * @param cmderr start-up errors and debugging info
+     * @param console console control interaction
+     * @param userin code execution input (not yet functional)
+     * @param userout code execution output  -- System.out.printf("hi")
+     * @param usererr code execution error stream  -- System.err.printf("Oops")
+     */
+    public JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr,
+            PrintStream console,
+            InputStream userin, PrintStream userout, PrintStream usererr) {
+        this.cmdin = cmdin;
+        this.cmdout = cmdout;
+        this.cmderr = cmderr;
+        this.console = console;
+        this.userin = userin;
+        this.userout = userout;
+        this.usererr = usererr;
+    }
+
+    private IOContext input = null;
+    private boolean regenerateOnDeath = true;
+    private boolean live = false;
+
+    SourceCodeAnalysis analysis;
+    JShell state = null;
+    Subscription shutdownSubscription = null;
+
+    private boolean debug = false;
+    private boolean displayPrompt = true;
+    public boolean testPrompt = false;
+    private Feedback feedback = Feedback.Default;
+    private String cmdlineClasspath = null;
+    private String cmdlineStartup = null;
+    private String editor = null;
+
+    static final Preferences PREFS = Preferences.userRoot().node("tool/REPL");
+
+    static final String STARTUP_KEY = "STARTUP";
+
+    static final String DEFAULT_STARTUP =
+            "\n" +
+            "import java.util.*;\n" +
+            "import java.io.*;\n" +
+            "import java.math.*;\n" +
+            "import java.net.*;\n" +
+            "import java.util.concurrent.*;\n" +
+            "import java.util.prefs.*;\n" +
+            "import java.util.regex.*;\n" +
+            "void printf(String format, Object... args) { System.out.printf(format, args); }\n";
+
+    // Tool id (tid) mapping
+    NameSpace mainNamespace;
+    NameSpace startNamespace;
+    NameSpace errorNamespace;
+    NameSpace currentNameSpace;
+    Map<Snippet,SnippetInfo> mapSnippet;
+
+    void debug(String format, Object... args) {
+        if (debug) {
+            cmderr.printf(format + "\n", args);
+        }
+    }
+
+    /**
+     * For more verbose feedback modes
+     * @param format printf format
+     * @param args printf args
+     */
+    void fluff(String format, Object... args) {
+        if (feedback() != Feedback.Off && feedback() != Feedback.Concise) {
+            hard(format, args);
+        }
+    }
+
+    /**
+     * For concise feedback mode only
+     * @param format printf format
+     * @param args printf args
+     */
+    void concise(String format, Object... args) {
+        if (feedback() == Feedback.Concise) {
+            hard(format, args);
+        }
+    }
+
+    /**
+     * For all feedback modes -- must show
+     * @param format printf format
+     * @param args printf args
+     */
+    void hard(String format, Object... args) {
+        cmdout.printf("|  " + format + "\n", args);
+    }
+
+    /**
+     * Trim whitespace off end of string
+     * @param s
+     * @return
+     */
+    static String trimEnd(String s) {
+        int last = s.length() - 1;
+        int i = last;
+        while (i >= 0 && Character.isWhitespace(s.charAt(i))) {
+            --i;
+        }
+        if (i != last) {
+            return s.substring(0, i + 1);
+        } else {
+            return s;
+        }
+    }
+
+    /**
+     * Normal start entry point
+     * @param args
+     * @throws Exception
+     */
+    public static void main(String[] args) throws Exception {
+        new JShellTool(System.in, System.out, System.err, System.out,
+                 new ByteArrayInputStream(new byte[0]), System.out, System.err)
+                .start(args);
+    }
+
+    public void start(String[] args) throws Exception {
+        List<String> loadList = processCommandArgs(args);
+        if (loadList == null) {
+            // Abort
+            return;
+        }
+        try (IOContext in = new ConsoleIOContext(this, cmdin, console)) {
+            start(in, loadList);
+        }
+    }
+
+    private void start(IOContext in, List<String> loadList) {
+        resetState(); // Initialize
+
+        for (String loadFile : loadList) {
+            cmdOpen(loadFile);
+        }
+
+        if (regenerateOnDeath) {
+            fluff("Welcome to JShell -- Version %s", version());
+            fluff("Type /help for help");
+        }
+
+        try {
+            while (regenerateOnDeath) {
+                if (!live) {
+                    resetState();
+                }
+                run(in);
+            }
+        } finally {
+            closeState();
+        }
+    }
+
+    /**
+     * Process the command line arguments.
+     * Set options.
+     * @param args the command line arguments
+     * @return the list of files to be loaded
+     */
+    private List<String> processCommandArgs(String[] args) {
+        List<String> loadList = new ArrayList<>();
+        Iterator<String> ai = Arrays.asList(args).iterator();
+        while (ai.hasNext()) {
+            String arg = ai.next();
+            if (arg.startsWith("-")) {
+                switch (arg) {
+                    case "-classpath":
+                    case "-cp":
+                        if (cmdlineClasspath != null) {
+                            cmderr.printf("Conflicting -classpath option.\n");
+                            return null;
+                        }
+                        if (ai.hasNext()) {
+                            cmdlineClasspath = ai.next();
+                        } else {
+                            cmderr.printf("Argument to -classpath missing.\n");
+                            return null;
+                        }
+                        break;
+                    case "-help":
+                        printUsage();
+                        return null;
+                    case "-version":
+                        cmdout.printf("jshell %s\n", version());
+                        return null;
+                    case "-fullversion":
+                        cmdout.printf("jshell %s\n", fullVersion());
+                        return null;
+                    case "-startup":
+                        if (cmdlineStartup != null) {
+                            cmderr.printf("Conflicting -startup or -nostartup option.\n");
+                            return null;
+                        }
+                        if (ai.hasNext()) {
+                            String filename = ai.next();
+                            try {
+                                byte[] encoded = Files.readAllBytes(Paths.get(filename));
+                                cmdlineStartup = new String(encoded);
+                            } catch (AccessDeniedException e) {
+                                hard("File '%s' for start-up is not accessible.", filename);
+                            } catch (NoSuchFileException e) {
+                                hard("File '%s' for start-up is not found.", filename);
+                            } catch (Exception e) {
+                                hard("Exception while reading start-up file: %s", e);
+                            }
+                        } else {
+                            cmderr.printf("Argument to -startup missing.\n");
+                            return null;
+                        }
+                        break;
+                    case "-nostartup":
+                        if (cmdlineStartup != null && !cmdlineStartup.isEmpty()) {
+                            cmderr.printf("Conflicting -startup option.\n");
+                            return null;
+                        }
+                        cmdlineStartup = "";
+                        break;
+                    default:
+                        cmderr.printf("Unknown option: %s\n", arg);
+                        printUsage();
+                        return null;
+                }
+            } else {
+                loadList.add(arg);
+            }
+        }
+        return loadList;
+    }
+
+    private void printUsage() {
+        cmdout.printf("Usage:   jshell <options> <load files>\n");
+        cmdout.printf("where possible options include:\n");
+        cmdout.printf("  -classpath <path>          Specify where to find user class files\n");
+        cmdout.printf("  -cp <path>                 Specify where to find user class files\n");
+        cmdout.printf("  -startup <file>            One run replacement for the start-up definitions\n");
+        cmdout.printf("  -nostartup                 Do not run the start-up definitions\n");
+        cmdout.printf("  -help                      Print a synopsis of standard options\n");
+        cmdout.printf("  -version                   Version information\n");
+    }
+
+    private void resetState() {
+        closeState();
+
+        // Initialize tool id mapping
+        mainNamespace = new NameSpace("main", "");
+        startNamespace = new NameSpace("start", "s");
+        errorNamespace = new NameSpace("error", "e");
+        mapSnippet = new LinkedHashMap<>();
+        currentNameSpace = startNamespace;
+
+        state = JShell.builder()
+                .in(userin)
+                .out(userout)
+                .err(usererr)
+                .tempVariableNameGenerator(()-> "$" + currentNameSpace.tidNext())
+                .idGenerator((sn, i) -> (currentNameSpace == startNamespace || state.status(sn).isActive)
+                        ? currentNameSpace.tid(sn)
+                        : errorNamespace.tid(sn))
+                .build();
+        analysis = state.sourceCodeAnalysis();
+        shutdownSubscription = state.onShutdown((JShell deadState) -> {
+            if (deadState == state) {
+                hard("State engine terminated.  See /history");
+                live = false;
+            }
+        });
+        live = true;
+
+        if (cmdlineClasspath != null) {
+            state.addToClasspath(cmdlineClasspath);
+        }
+
+
+        String start;
+        if (cmdlineStartup == null) {
+            start = PREFS.get(STARTUP_KEY, "<nada>");
+            if (start.equals("<nada>")) {
+                start = DEFAULT_STARTUP;
+                PREFS.put(STARTUP_KEY, DEFAULT_STARTUP);
+            }
+        } else {
+            start = cmdlineStartup;
+        }
+        try (IOContext suin = new FileScannerIOContext(new StringReader(start))) {
+            run(suin);
+        } catch (Exception ex) {
+            hard("Unexpected exception reading start-up: %s\n", ex);
+        }
+        currentNameSpace = mainNamespace;
+    }
+
+    private void closeState() {
+        live = false;
+        JShell oldState = state;
+        if (oldState != null) {
+            oldState.unsubscribe(shutdownSubscription); // No notification
+            oldState.close();
+        }
+    }
+
+    /**
+     * Main loop
+     * @param in the line input/editing context
+     */
+    private void run(IOContext in) {
+        IOContext oldInput = input;
+        input = in;
+        try {
+            String incomplete = "";
+            while (live) {
+                String prompt;
+                if (in.interactiveOutput() && displayPrompt) {
+                    prompt = testPrompt
+                                    ? incomplete.isEmpty()
+                                            ? "\u0005" //ENQ
+                                            : "\u0006" //ACK
+                                    : incomplete.isEmpty()
+                                            ? feedback() == Feedback.Concise
+                                                    ? "-> "
+                                                    : "\n-> "
+                                            : ">> "
+                    ;
+                } else {
+                    prompt = "";
+                }
+                String raw;
+                try {
+                    raw = in.readLine(prompt, incomplete);
+                } catch (InputInterruptedException ex) {
+                    //input interrupted - clearing current state
+                    incomplete = "";
+                    continue;
+                }
+                if (raw == null) {
+                    //EOF
+                    if (in.interactiveOutput()) {
+                        // End after user ctrl-D
+                        regenerateOnDeath = false;
+                    }
+                    break;
+                }
+                String trimmed = trimEnd(raw);
+                if (!trimmed.isEmpty()) {
+                    String line = incomplete + trimmed;
+
+                    // No commands in the middle of unprocessed source
+                    if (incomplete.isEmpty() && line.startsWith("/") && !line.startsWith("//") && !line.startsWith("/*")) {
+                        processCommand(line.trim());
+                    } else {
+                        incomplete = processSourceCatchingReset(line);
+                    }
+                }
+            }
+        } catch (IOException ex) {
+            hard("Unexpected exception: %s\n", ex);
+        } finally {
+            input = oldInput;
+        }
+    }
+
+    private String processSourceCatchingReset(String src) {
+        try {
+            input.beforeUserCode();
+            return processSource(src);
+        } catch (IllegalStateException ex) {
+            hard("Resetting...");
+            live = false; // Make double sure
+            return "";
+        } finally {
+            input.afterUserCode();
+        }
+    }
+
+    private void processCommand(String cmd) {
+        try {
+            //handle "/[number]"
+            cmdUseHistoryEntry(Integer.parseInt(cmd.substring(1)));
+            return ;
+        } catch (NumberFormatException ex) {
+            //ignore
+        }
+        String arg = "";
+        int idx = cmd.indexOf(' ');
+        if (idx > 0) {
+            arg = cmd.substring(idx + 1).trim();
+            cmd = cmd.substring(0, idx);
+        }
+        Command command = commands.get(cmd);
+        if (command == null || command.kind == CommandKind.HELP_ONLY) {
+            hard("No such command: %s", cmd);
+            fluff("Type /help for help.");
+        } else {
+            command.run.accept(arg);
+        }
+    }
+
+    private static Path toPathResolvingUserHome(String pathString) {
+        if (pathString.replace(File.separatorChar, '/').startsWith("~/"))
+            return Paths.get(System.getProperty("user.home"), pathString.substring(2));
+        else
+            return Paths.get(pathString);
+    }
+
+    static final class Command {
+        public final String[] aliases;
+        public final String params;
+        public final String description;
+        public final Consumer<String> run;
+        public final CompletionProvider completions;
+        public final CommandKind kind;
+
+        public Command(String command, String alias, String params, String description, Consumer<String> run, CompletionProvider completions) {
+            this(command, alias, params, description, run, completions, CommandKind.NORMAL);
+        }
+
+        public Command(String command, String alias, String params, String description, Consumer<String> run, CompletionProvider completions, CommandKind kind) {
+            this.aliases = alias != null ? new String[] {command, alias} : new String[] {command};
+            this.params = params;
+            this.description = description;
+            this.run = run;
+            this.completions = completions;
+            this.kind = kind;
+        }
+
+    }
+
+    interface CompletionProvider {
+        List<Suggestion> completionSuggestions(String input, int cursor, int[] anchor);
+    }
+
+    enum CommandKind {
+        NORMAL,
+        HIDDEN,
+        HELP_ONLY;
+    }
+
+    static final class FixedCompletionProvider implements CompletionProvider {
+
+        private final String[] alternatives;
+
+        public FixedCompletionProvider(String... alternatives) {
+            this.alternatives = alternatives;
+        }
+
+        @Override
+        public List<Suggestion> completionSuggestions(String input, int cursor, int[] anchor) {
+            List<Suggestion> result = new ArrayList<>();
+
+            for (String alternative : alternatives) {
+                if (alternative.startsWith(input)) {
+                    result.add(new Suggestion(alternative, false));
+                }
+            }
+
+            anchor[0] = 0;
+
+            return result;
+        }
+
+    }
+
+    private static final CompletionProvider EMPTY_COMPLETION_PROVIDER = new FixedCompletionProvider();
+    private static final CompletionProvider FILE_COMPLETION_PROVIDER = fileCompletions(p -> true);
+    private final Map<String, Command> commands = new LinkedHashMap<>();
+    private void registerCommand(Command cmd) {
+        for (String str : cmd.aliases) {
+            commands.put(str, cmd);
+        }
+    }
+    private static CompletionProvider fileCompletions(Predicate<Path> accept) {
+        return (code, cursor, anchor) -> {
+            int lastSlash = code.lastIndexOf('/');
+            String path = code.substring(0, lastSlash + 1);
+            String prefix = lastSlash != (-1) ? code.substring(lastSlash + 1) : code;
+            Path current = toPathResolvingUserHome(path);
+            List<Suggestion> result = new ArrayList<>();
+            try (Stream<Path> dir = Files.list(current)) {
+                dir.filter(f -> accept.test(f) && f.getFileName().toString().startsWith(prefix))
+                   .map(f -> new Suggestion(f.getFileName() + (Files.isDirectory(f) ? "/" : ""), false))
+                   .forEach(result::add);
+            } catch (IOException ex) {
+                //ignore...
+            }
+            if (path.isEmpty()) {
+                StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
+                             .filter(root -> accept.test(root) && root.toString().startsWith(prefix))
+                             .map(root -> new Suggestion(root.toString(), false))
+                             .forEach(result::add);
+            }
+            anchor[0] = path.length();
+            return result;
+        };
+    }
+
+    private static CompletionProvider classPathCompletion() {
+        return fileCompletions(p -> Files.isDirectory(p) ||
+                                    p.getFileName().toString().endsWith(".zip") ||
+                                    p.getFileName().toString().endsWith(".jar"));
+    }
+
+    private CompletionProvider editCompletion() {
+        return (prefix, cursor, anchor) -> {
+            anchor[0] = 0;
+            return state.snippets()
+                        .stream()
+                        .flatMap(k -> (k instanceof DeclarationSnippet)
+                                ? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
+                                : Stream.of(String.valueOf(k.id())))
+                        .filter(k -> k.startsWith(prefix))
+                        .map(k -> new Suggestion(k, false))
+                        .collect(Collectors.toList());
+        };
+    }
+
+    private static CompletionProvider saveCompletion() {
+        CompletionProvider keyCompletion = new FixedCompletionProvider("all ", "history ");
+        return (code, cursor, anchor) -> {
+            List<Suggestion> result = new ArrayList<>();
+            int space = code.indexOf(' ');
+            if (space == (-1)) {
+                result.addAll(keyCompletion.completionSuggestions(code, cursor, anchor));
+            }
+            result.addAll(FILE_COMPLETION_PROVIDER.completionSuggestions(code.substring(space + 1), cursor - space - 1, anchor));
+            anchor[0] += space + 1;
+            return result;
+        };
+    }
+
+    // Table of commands -- with command forms, argument kinds, help message, implementation, ...
+
+    {
+        registerCommand(new Command("/list", "/l", "[all]", "list the source you have typed",
+                                    arg -> cmdList(arg),
+                                    new FixedCompletionProvider("all")));
+        registerCommand(new Command("/seteditor", null, "<executable>", "set the external editor command to use",
+                                    arg -> cmdSetEditor(arg),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/edit", "/e", "<name or id>", "edit a source entry referenced by name or id",
+                                    arg -> cmdEdit(arg),
+                                    editCompletion()));
+        registerCommand(new Command("/drop", "/d", "<name or id>", "delete a source entry referenced by name or id",
+                                    arg -> cmdDrop(arg),
+                                    editCompletion()));
+        registerCommand(new Command("/save", "/s", "[all|history] <file>", "save the source you have typed",
+                                    arg -> cmdSave(arg),
+                                    saveCompletion()));
+        registerCommand(new Command("/open", "/o", "<file>", "open a file as source input",
+                                    arg -> cmdOpen(arg),
+                                    FILE_COMPLETION_PROVIDER));
+        registerCommand(new Command("/vars", "/v", null, "list the declared variables and their values",
+                                    arg -> cmdVars(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/methods", "/m", null, "list the declared methods and their signatures",
+                                    arg -> cmdMethods(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/classes", "/c", null, "list the declared classes",
+                                    arg -> cmdClasses(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/exit", "/x", null, "exit the REPL",
+                                    arg -> cmdExit(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/reset", "/r", null, "reset everything in the REPL",
+                                    arg -> cmdReset(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/feedback", "/f", "<level>", "feedback information: off, concise, normal, verbose, default, or ?",
+                                    arg -> cmdFeedback(arg),
+                                    new FixedCompletionProvider("off", "concise", "normal", "verbose", "default", "?")));
+        registerCommand(new Command("/prompt", "/p", null, "toggle display of a prompt",
+                                    arg -> cmdPrompt(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/classpath", "/cp", "<path>", "add a path to the classpath",
+                                    arg -> cmdClasspath(arg),
+                                    classPathCompletion()));
+        registerCommand(new Command("/history", "/h", null, "history of what you have typed",
+                                    arg -> cmdHistory(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/setstart", null, "<file>", "read file and set as the new start-up definitions",
+                                    arg -> cmdSetStart(arg),
+                                    FILE_COMPLETION_PROVIDER));
+        registerCommand(new Command("/savestart", null, "<file>", "save the default start-up definitions to the file",
+                                    arg -> cmdSaveStart(arg),
+                                    FILE_COMPLETION_PROVIDER));
+        registerCommand(new Command("/debug", "/db", "", "toggle debugging of the REPL",
+                                    arg -> cmdDebug(arg),
+                                    EMPTY_COMPLETION_PROVIDER,
+                                    CommandKind.HIDDEN));
+        registerCommand(new Command("/help", "/?", "", "this help message",
+                                    arg -> cmdHelp(),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/!", null, "", "re-run last snippet",
+                                    arg -> cmdUseHistoryEntry(-1),
+                                    EMPTY_COMPLETION_PROVIDER));
+        registerCommand(new Command("/<n>", null, "", "re-run n-th snippet",
+                                    arg -> { throw new IllegalStateException(); },
+                                    EMPTY_COMPLETION_PROVIDER,
+                                    CommandKind.HELP_ONLY));
+        registerCommand(new Command("/-<n>", null, "", "re-run n-th previous snippet",
+                                    arg -> { throw new IllegalStateException(); },
+                                    EMPTY_COMPLETION_PROVIDER,
+                                    CommandKind.HELP_ONLY));
+    }
+
+    public List<Suggestion> commandCompletionSuggestions(String code, int cursor, int[] anchor) {
+        String prefix = code.substring(0, cursor);
+        int space = prefix.indexOf(' ');
+        Stream<Suggestion> result;
+
+        if (space == (-1)) {
+            result = commands.values()
+                             .stream()
+                             .distinct()
+                             .filter(cmd -> cmd.kind != CommandKind.HIDDEN && cmd.kind != CommandKind.HELP_ONLY)
+                             .map(cmd -> cmd.aliases[0])
+                             .filter(key -> key.startsWith(prefix))
+                             .map(key -> new Suggestion(key + " ", false));
+            anchor[0] = 0;
+        } else {
+            String arg = prefix.substring(space + 1);
+            String cmd = prefix.substring(0, space);
+            Command command = commands.get(cmd);
+            if (command != null) {
+                result = command.completions.completionSuggestions(arg, cursor - space, anchor).stream();
+                anchor[0] += space + 1;
+            } else {
+                result = Stream.empty();
+            }
+        }
+
+        return result.sorted((s1, s2) -> s1.continuation.compareTo(s2.continuation))
+                     .collect(Collectors.toList());
+    }
+
+    public String commandDocumentation(String code, int cursor) {
+        code = code.substring(0, cursor);
+        int space = code.indexOf(' ');
+
+        if (space != (-1)) {
+            String cmd = code.substring(0, space);
+            Command command = commands.get(cmd);
+            if (command != null) {
+                return command.description;
+            }
+        }
+
+        return null;
+    }
+
+    // --- Command implementations ---
+
+    void cmdSetEditor(String arg) {
+        if (arg.isEmpty()) {
+            hard("/seteditor requires a path argument");
+        } else {
+            editor = arg;
+            fluff("Editor set to: %s", arg);
+        }
+    }
+
+    void cmdClasspath(String arg) {
+        if (arg.isEmpty()) {
+            hard("/classpath requires a path argument");
+        } else {
+            state.addToClasspath(toPathResolvingUserHome(arg).toString());
+            fluff("Path %s added to classpath", arg);
+        }
+    }
+
+    void cmdDebug(String arg) {
+        if (arg.isEmpty()) {
+            debug = !debug;
+            InternalDebugControl.setDebugFlags(state, debug ? InternalDebugControl.DBG_GEN : 0);
+            fluff("Debugging %s", debug ? "on" : "off");
+        } else {
+            int flags = 0;
+            for (char ch : arg.toCharArray()) {
+                switch (ch) {
+                    case '0':
+                        flags = 0;
+                        debug = false;
+                        fluff("Debugging off");
+                        break;
+                    case 'r':
+                        debug = true;
+                        fluff("REPL tool debugging on");
+                        break;
+                    case 'g':
+                        flags |= InternalDebugControl.DBG_GEN;
+                        fluff("General debugging on");
+                        break;
+                    case 'f':
+                        flags |= InternalDebugControl.DBG_FMGR;
+                        fluff("File manager debugging on");
+                        break;
+                    case 'c':
+                        flags |= InternalDebugControl.DBG_COMPA;
+                        fluff("Completion analysis debugging on");
+                        break;
+                    case 'd':
+                        flags |= InternalDebugControl.DBG_DEP;
+                        fluff("Dependency debugging on");
+                        break;
+                    case 'e':
+                        flags |= InternalDebugControl.DBG_EVNT;
+                        fluff("Event debugging on");
+                        break;
+                    default:
+                        hard("Unknown debugging option: %c", ch);
+                        fluff("Use: 0 r g f c d");
+                        break;
+                }
+            }
+            InternalDebugControl.setDebugFlags(state, flags);
+        }
+    }
+
+    private void cmdExit() {
+        regenerateOnDeath = false;
+        live = false;
+        fluff("Goodbye\n");
+    }
+
+    private void cmdFeedback(String arg) {
+        switch (arg) {
+            case "":
+            case "d":
+            case "default":
+                feedback = Feedback.Default;
+                break;
+            case "o":
+            case "off":
+                feedback = Feedback.Off;
+                break;
+            case "c":
+            case "concise":
+                feedback = Feedback.Concise;
+                break;
+            case "n":
+            case "normal":
+                feedback = Feedback.Normal;
+                break;
+            case "v":
+            case "verbose":
+                feedback = Feedback.Verbose;
+                break;
+            default:
+                hard("Follow /feedback with of the following:");
+                hard("  off       (errors and critical output only)");
+                hard("  concise");
+                hard("  normal");
+                hard("  verbose");
+                hard("  default");
+                hard("You may also use just the first letter, for example: /f c");
+                hard("In interactive mode 'default' is the same as 'normal', from a file it is the same as 'off'");
+                return;
+        }
+        fluff("Feedback mode: %s", feedback.name().toLowerCase());
+    }
+
+    void cmdHelp() {
+        int synopsisLen = 0;
+        Map<String, String> synopsis2Description = new LinkedHashMap<>();
+        for (Command cmd : new LinkedHashSet<>(commands.values())) {
+            if (cmd.kind == CommandKind.HIDDEN)
+                continue;
+            StringBuilder synopsis = new StringBuilder();
+            if (cmd.aliases.length > 1) {
+                synopsis.append(String.format("%-3s or ", cmd.aliases[1]));
+            } else {
+                synopsis.append("       ");
+            }
+            synopsis.append(cmd.aliases[0]);
+            if (cmd.params != null)
+                synopsis.append(" ").append(cmd.params);
+            synopsis2Description.put(synopsis.toString(), cmd.description);
+            synopsisLen = Math.max(synopsisLen, synopsis.length());
+        }
+        cmdout.println("Type a Java language expression, statement, or declaration.");
+        cmdout.println("Or type one of the following commands:\n");
+        for (Entry<String, String> e : synopsis2Description.entrySet()) {
+            cmdout.print(String.format("%-" + synopsisLen + "s", e.getKey()));
+            cmdout.print(" -- ");
+            cmdout.println(e.getValue());
+        }
+        cmdout.println();
+        cmdout.println("Supported shortcuts include:");
+        cmdout.println("<tab>       -- show possible completions for the current text");
+        cmdout.println("Shift-<tab> -- for current method or constructor invocation, show a synopsis of the method/constructor");
+    }
+
+    private void cmdHistory() {
+        cmdout.println();
+        for (String s : input.currentSessionHistory()) {
+            // No number prefix, confusing with snippet ids
+            cmdout.printf("%s\n", s);
+        }
+    }
+
+    /**
+     * Convert a user argument to a list of snippets referenced by that
+     * argument (or lack of argument).
+     * @param arg The user's argument to the command
+     * @return a list of referenced snippets
+     */
+    private List<Snippet> argToSnippets(String arg) {
+        List<Snippet> snippets = new ArrayList<>();
+        if (arg.isEmpty()) {
+            // Default is all user snippets
+            for (Snippet sn : state.snippets()) {
+                if (notInStartUp(sn)) {
+                    snippets.add(sn);
+                }
+            }
+        } else {
+            // Look for all declarations with matching names
+            for (Snippet key : state.snippets()) {
+                switch (key.kind()) {
+                    case METHOD:
+                    case VAR:
+                    case TYPE_DECL:
+                        if (((DeclarationSnippet) key).name().equals(arg)) {
+                            snippets.add(key);
+                        }
+                        break;
+                }
+            }
+            // If no declarations found, look for an id of this name
+            if (snippets.isEmpty()) {
+                for (Snippet sn : state.snippets()) {
+                    if (sn.id().equals(arg)) {
+                        snippets.add(sn);
+                        break;
+                    }
+                }
+            }
+            // If still no matches found, give an error
+            if (snippets.isEmpty()) {
+                hard("No definition or id named %s found.  See /classes /methods /vars or /list", arg);
+                return null;
+            }
+        }
+        return snippets;
+    }
+
+    private void cmdDrop(String arg) {
+        if (arg.isEmpty()) {
+            hard("In the /drop argument, please specify an import, variable, method, or class to drop.");
+            hard("Specify by id or name. Use /list to see ids. Use /reset to reset all state.");
+            return;
+        }
+        List<Snippet> snippetSet = argToSnippets(arg);
+        if (snippetSet == null) {
+            return;
+        }
+        snippetSet = snippetSet.stream()
+                .filter(sn -> state.status(sn).isActive)
+                .collect(toList());
+        snippetSet.removeIf(sn -> !(sn instanceof PersistentSnippet));
+        if (snippetSet.isEmpty()) {
+            hard("The argument did not specify an import, variable, method, or class to drop.");
+            return;
+        }
+        if (snippetSet.size() > 1) {
+            hard("The argument references more than one import, variable, method, or class.");
+            hard("Try again with one of the ids below:");
+            for (Snippet sn : snippetSet) {
+                cmdout.printf("%4s : %s\n", sn.id(), sn.source().replace("\n", "\n       "));
+            }
+            return;
+        }
+        PersistentSnippet psn = (PersistentSnippet) snippetSet.iterator().next();
+        state.drop(psn).forEach(this::handleEvent);
+    }
+
+    private void cmdEdit(String arg) {
+        List<Snippet> snippetSet = argToSnippets(arg);
+        if (snippetSet == null) {
+            return;
+        }
+        Set<String> srcSet = new LinkedHashSet<>();
+        for (Snippet key : snippetSet) {
+            String src = key.source();
+            switch (key.subKind()) {
+                case VAR_VALUE_SUBKIND:
+                    break;
+                case ASSIGNMENT_SUBKIND:
+                case OTHER_EXPRESSION_SUBKIND:
+                case TEMP_VAR_EXPRESSION_SUBKIND:
+                    if (!src.endsWith(";")) {
+                        src = src + ";";
+                    }
+                    srcSet.add(src);
+                    break;
+                default:
+                    srcSet.add(src);
+                    break;
+            }
+        }
+        StringBuilder sb = new StringBuilder();
+        for (String s : srcSet) {
+            sb.append(s);
+            sb.append('\n');
+        }
+        String src = sb.toString();
+        Consumer<String> saveHandler = new SaveHandler(src, srcSet);
+        Consumer<String> errorHandler = s -> hard("Edit Error: %s", s);
+        if (editor == null) {
+            EditPad.edit(errorHandler, src, saveHandler);
+        } else {
+            ExternalEditor.edit(editor, errorHandler, src, saveHandler, input);
+        }
+    }
+    //where
+    // receives editor requests to save
+    private class SaveHandler implements Consumer<String> {
+
+        String src;
+        Set<String> currSrcs;
+
+        SaveHandler(String src, Set<String> ss) {
+            this.src = src;
+            this.currSrcs = ss;
+        }
+
+        @Override
+        public void accept(String s) {
+            if (!s.equals(src)) { // quick check first
+                src = s;
+                try {
+                    Set<String> nextSrcs = new LinkedHashSet<>();
+                    boolean failed = false;
+                    while (true) {
+                        CompletionInfo an = analysis.analyzeCompletion(s);
+                        if (!an.completeness.isComplete) {
+                            break;
+                        }
+                        String tsrc = trimNewlines(an.source);
+                        if (!failed && !currSrcs.contains(tsrc)) {
+                            failed = processCompleteSource(tsrc);
+                        }
+                        nextSrcs.add(tsrc);
+                        if (an.remaining.isEmpty()) {
+                            break;
+                        }
+                        s = an.remaining;
+                    }
+                    currSrcs = nextSrcs;
+                } catch (IllegalStateException ex) {
+                    hard("Resetting...");
+                    resetState();
+                    currSrcs = new LinkedHashSet<>(); // re-process everything
+                }
+            }
+        }
+
+        private String trimNewlines(String s) {
+            int b = 0;
+            while (b < s.length() && s.charAt(b) == '\n') {
+                ++b;
+            }
+            int e = s.length() -1;
+            while (e >= 0 && s.charAt(e) == '\n') {
+                --e;
+            }
+            return s.substring(b, e + 1);
+        }
+    }
+
+    private void cmdList(String arg) {
+        boolean all = false;
+        switch (arg) {
+            case "all":
+                all = true;
+                break;
+            case "history":
+                cmdHistory();
+                return;
+            case "":
+                break;
+            default:
+                hard("Invalid /list argument: %s", arg);
+                return;
+        }
+        boolean hasOutput = false;
+        for (Snippet sn : state.snippets()) {
+            if (all || (notInStartUp(sn) && state.status(sn).isActive)) {
+                if (!hasOutput) {
+                    cmdout.println();
+                    hasOutput = true;
+                }
+                cmdout.printf("%4s : %s\n", sn.id(), sn.source().replace("\n", "\n       "));
+
+            }
+        }
+    }
+
+    private void cmdOpen(String filename) {
+        if (filename.isEmpty()) {
+            hard("The /open command requires a filename argument.");
+        } else {
+            try {
+                run(new FileScannerIOContext(toPathResolvingUserHome(filename).toString()));
+            } catch (FileNotFoundException e) {
+                hard("File '%s' is not found: %s", filename, e.getMessage());
+            } catch (Exception e) {
+                hard("Exception while reading file: %s", e);
+            }
+        }
+    }
+
+    private void cmdPrompt() {
+        displayPrompt = !displayPrompt;
+        fluff("Prompt will %sdisplay. Use /prompt to toggle.", displayPrompt ? "" : "NOT ");
+        concise("Prompt: %s", displayPrompt ? "on" : "off");
+    }
+
+    private void cmdReset() {
+        live = false;
+        fluff("Resetting state.");
+    }
+
+    private void cmdSave(String arg_filename) {
+        Matcher mat = HISTORY_ALL_FILENAME.matcher(arg_filename);
+        if (!mat.find()) {
+            hard("Malformed argument to the /save command: %s", arg_filename);
+            return;
+        }
+        boolean useHistory = false;
+        boolean saveAll = false;
+        String cmd = mat.group("cmd");
+        if (cmd != null) switch (cmd) {
+            case "all":
+                saveAll = true;
+                break;
+            case "history":
+                useHistory = true;
+                break;
+        }
+        String filename = mat.group("filename");
+        if (filename == null ||filename.isEmpty()) {
+            hard("The /save command requires a filename argument.");
+            return;
+        }
+        try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename),
+                Charset.defaultCharset(),
+                CREATE, TRUNCATE_EXISTING, WRITE)) {
+            if (useHistory) {
+                for (String s : input.currentSessionHistory()) {
+                    writer.write(s);
+                    writer.write("\n");
+                }
+            } else {
+                for (Snippet sn : state.snippets()) {
+                    if (saveAll || notInStartUp(sn)) {
+                        writer.write(sn.source());
+                        writer.write("\n");
+                    }
+                }
+            }
+        } catch (FileNotFoundException e) {
+            hard("File '%s' for save is not accessible: %s", filename, e.getMessage());
+        } catch (Exception e) {
+            hard("Exception while saving: %s", e);
+        }
+    }
+
+    private void cmdSetStart(String filename) {
+        if (filename.isEmpty()) {
+            hard("The /setstart command requires a filename argument.");
+        } else {
+            try {
+                byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
+                String init = new String(encoded);
+                PREFS.put(STARTUP_KEY, init);
+            } catch (AccessDeniedException e) {
+                hard("File '%s' for /setstart is not accessible.", filename);
+            } catch (NoSuchFileException e) {
+                hard("File '%s' for /setstart is not found.", filename);
+            } catch (Exception e) {
+                hard("Exception while reading start set file: %s", e);
+            }
+        }
+    }
+
+    private void cmdSaveStart(String filename) {
+        if (filename.isEmpty()) {
+            hard("The /savestart command requires a filename argument.");
+        } else {
+            try {
+                Files.write(toPathResolvingUserHome(filename), DEFAULT_STARTUP.getBytes());
+            } catch (AccessDeniedException e) {
+                hard("File '%s' for /savestart is not accessible.", filename);
+            } catch (NoSuchFileException e) {
+                hard("File '%s' for /savestart cannot be located.", filename);
+            } catch (Exception e) {
+                hard("Exception while saving default startup file: %s", e);
+            }
+        }
+    }
+
+    private void cmdVars() {
+        for (VarSnippet vk : state.variables()) {
+            String val = state.status(vk) == Status.VALID
+                    ? state.varValue(vk)
+                    : "(not-active)";
+            hard("  %s %s = %s", vk.typeName(), vk.name(), val);
+        }
+    }
+
+    private void cmdMethods() {
+        for (MethodSnippet mk : state.methods()) {
+            hard("  %s %s", mk.name(), mk.signature());
+        }
+    }
+
+    private void cmdClasses() {
+        for (TypeDeclSnippet ck : state.types()) {
+            String kind;
+            switch (ck.subKind()) {
+                case INTERFACE_SUBKIND:
+                    kind = "interface";
+                    break;
+                case CLASS_SUBKIND:
+                    kind = "class";
+                    break;
+                case ENUM_SUBKIND:
+                    kind = "enum";
+                    break;
+                case ANNOTATION_TYPE_SUBKIND:
+                    kind = "@interface";
+                    break;
+                default:
+                    assert false : "Wrong kind" + ck.subKind();
+                    kind = "class";
+                    break;
+            }
+            hard("  %s %s", kind, ck.name());
+        }
+    }
+
+    private void cmdUseHistoryEntry(int index) {
+        List<Snippet> keys = state.snippets();
+        if (index < 0)
+            index += keys.size();
+        else
+            index--;
+        if (index >= 0 && index < keys.size()) {
+            String source = keys.get(index).source();
+            cmdout.printf("%s\n", source);
+            input.replaceLastHistoryEntry(source);
+            processSourceCatchingReset(source);
+        } else {
+            hard("Cannot find snippet %d", index + 1);
+        }
+    }
+
+    /**
+     * Filter diagnostics for only errors (no warnings, ...)
+     * @param diagnostics input list
+     * @return filtered list
+     */
+    List<Diag> errorsOnly(List<Diag> diagnostics) {
+        return diagnostics.stream()
+                .filter(d -> d.isError())
+                .collect(toList());
+    }
+
+    void printDiagnostics(String source, List<Diag> diagnostics, boolean embed) {
+        String padding = embed? "    " : "";
+        for (Diag diag : diagnostics) {
+            //assert diag.getSource().equals(source);
+
+            if (!embed) {
+                if (diag.isError()) {
+                    hard("Error:");
+                } else {
+                    hard("Warning:");
+                }
+            }
+
+            for (String line : diag.getMessage(null).split("\\r?\\n")) {
+                if (!line.trim().startsWith("location:")) {
+                    hard("%s%s", padding, line);
+                }
+            }
+
+            int pstart = (int) diag.getStartPosition();
+            int pend = (int) diag.getEndPosition();
+            Matcher m = LINEBREAK.matcher(source);
+            int pstartl = 0;
+            int pendl = -2;
+            while (m.find(pstartl)) {
+                pendl = m.start();
+                if (pendl >= pstart) {
+                    break;
+                } else {
+                    pstartl = m.end();
+                }
+            }
+            if (pendl < pstart) {
+                pendl = source.length();
+            }
+            fluff("%s%s", padding, source.substring(pstartl, pendl));
+
+            StringBuilder sb = new StringBuilder();
+            int start = pstart - pstartl;
+            for (int i = 0; i < start; ++i) {
+                sb.append(' ');
+            }
+            sb.append('^');
+            boolean multiline = pend > pendl;
+            int end = (multiline ? pendl : pend) - pstartl - 1;
+            if (end > start) {
+                for (int i = start + 1; i < end; ++i) {
+                    sb.append('-');
+                }
+                if (multiline) {
+                    sb.append("-...");
+                } else {
+                    sb.append('^');
+                }
+            }
+            fluff("%s%s", padding, sb.toString());
+
+            debug("printDiagnostics start-pos = %d ==> %d -- wrap = %s", diag.getStartPosition(), start, this);
+            debug("Code: %s", diag.getCode());
+            debug("Pos: %d (%d - %d)", diag.getPosition(),
+                    diag.getStartPosition(), diag.getEndPosition());
+        }
+    }
+
+    private String processSource(String srcInput) throws IllegalStateException {
+        while (true) {
+            CompletionInfo an = analysis.analyzeCompletion(srcInput);
+            if (!an.completeness.isComplete) {
+                return an.remaining;
+            }
+            boolean failed = processCompleteSource(an.source);
+            if (failed || an.remaining.isEmpty()) {
+                return "";
+            }
+            srcInput = an.remaining;
+        }
+    }
+    //where
+    private boolean processCompleteSource(String source) throws IllegalStateException {
+        debug("Compiling: %s", source);
+        boolean failed = false;
+        List<SnippetEvent> events = state.eval(source);
+        for (SnippetEvent e : events) {
+            failed |= handleEvent(e);
+        }
+        return failed;
+    }
+
+    private boolean handleEvent(SnippetEvent ste) {
+        Snippet sn = ste.snippet();
+        if (sn == null) {
+            debug("Event with null key: %s", ste);
+            return false;
+        }
+        List<Diag> diagnostics = state.diagnostics(sn);
+        String source = sn.source();
+        if (ste.causeSnippet() == null) {
+            // main event
+            printDiagnostics(source, diagnostics, false);
+            if (ste.status().isActive) {
+                if (ste.exception() != null) {
+                    if (ste.exception() instanceof EvalException) {
+                        printEvalException((EvalException) ste.exception());
+                        return true;
+                    } else if (ste.exception() instanceof UnresolvedReferenceException) {
+                        printUnresolved((UnresolvedReferenceException) ste.exception());
+                    } else {
+                        hard("Unexpected execution exception: %s", ste.exception());
+                        return true;
+                    }
+                } else {
+                    displayDeclarationAndValue(ste, false, ste.value());
+                }
+            } else if (ste.status() == Status.REJECTED) {
+                if (diagnostics.isEmpty()) {
+                    hard("Failed.");
+                }
+                return true;
+            }
+        } else if (ste.status() == Status.REJECTED) {
+            //TODO -- I don't believe updates can cause failures any more
+            hard("Caused failure of dependent %s --", ((DeclarationSnippet) sn).name());
+            printDiagnostics(source, diagnostics, true);
+        } else {
+            // Update
+            SubKind subkind = sn.subKind();
+            if (sn instanceof DeclarationSnippet
+                    && (feedback() == Feedback.Verbose
+                    || ste.status() == Status.OVERWRITTEN
+                    || subkind == SubKind.VAR_DECLARATION_SUBKIND
+                    || subkind == SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND)) {
+                // Under the conditions, display update information
+                displayDeclarationAndValue(ste, true, null);
+                List<Diag> other = errorsOnly(diagnostics);
+                if (other.size() > 0) {
+                    printDiagnostics(source, other, true);
+                }
+            }
+        }
+        return false;
+    }
+
+    @SuppressWarnings("fallthrough")
+    private void displayDeclarationAndValue(SnippetEvent ste, boolean update, String value) {
+        Snippet key = ste.snippet();
+        String declared;
+        Status status = ste.status();
+        switch (status) {
+            case VALID:
+            case RECOVERABLE_DEFINED:
+            case RECOVERABLE_NOT_DEFINED:
+                if (ste.previousStatus().isActive) {
+                    declared = ste.isSignatureChange()
+                        ? "Replaced"
+                        : "Modified";
+                } else {
+                    declared = "Added";
+                }
+                break;
+            case OVERWRITTEN:
+                declared = "Overwrote";
+                break;
+            case DROPPED:
+                declared = "Dropped";
+                break;
+            case REJECTED:
+                declared = "Rejected";
+                break;
+            case NONEXISTENT:
+            default:
+                // Should not occur
+                declared = ste.previousStatus().toString() + "=>" + status.toString();
+        }
+        if (update) {
+            declared = "  Update " + declared.toLowerCase();
+        }
+        String however;
+        if (key instanceof DeclarationSnippet && (status == Status.RECOVERABLE_DEFINED || status == Status.RECOVERABLE_NOT_DEFINED)) {
+            String cannotUntil = (status == Status.RECOVERABLE_NOT_DEFINED)
+                    ? " cannot be referenced until"
+                    : " cannot be invoked until";
+            however = (update? " which" : ", however, it") + cannotUntil + unresolved((DeclarationSnippet) key);
+        } else {
+            however = "";
+        }
+        switch (key.subKind()) {
+            case CLASS_SUBKIND:
+                fluff("%s class %s%s", declared, ((TypeDeclSnippet) key).name(), however);
+                break;
+            case INTERFACE_SUBKIND:
+                fluff("%s interface %s%s", declared, ((TypeDeclSnippet) key).name(), however);
+                break;
+            case ENUM_SUBKIND:
+                fluff("%s enum %s%s", declared, ((TypeDeclSnippet) key).name(), however);
+                break;
+            case ANNOTATION_TYPE_SUBKIND:
+                fluff("%s annotation interface %s%s", declared, ((TypeDeclSnippet) key).name(), however);
+                break;
+            case METHOD_SUBKIND:
+                fluff("%s method %s(%s)%s", declared, ((MethodSnippet) key).name(),
+                        ((MethodSnippet) key).parameterTypes(), however);
+                break;
+            case VAR_DECLARATION_SUBKIND:
+                if (!update) {
+                    VarSnippet vk = (VarSnippet) key;
+                    if (status == Status.RECOVERABLE_NOT_DEFINED) {
+                        fluff("%s variable %s%s", declared, vk.name(), however);
+                    } else {
+                        fluff("%s variable %s of type %s%s", declared, vk.name(), vk.typeName(), however);
+                    }
+                    break;
+                }
+            // Fall through
+            case VAR_DECLARATION_WITH_INITIALIZER_SUBKIND: {
+                VarSnippet vk = (VarSnippet) key;
+                if (status == Status.RECOVERABLE_NOT_DEFINED) {
+                    if (!update) {
+                        fluff("%s variable %s%s", declared, vk.name(), however);
+                        break;
+                    }
+                } else if (update) {
+                    if (ste.isSignatureChange()) {
+                        hard("%s variable %s, reset to null", declared, vk.name());
+                    }
+                } else {
+                    fluff("%s variable %s of type %s with initial value %s",
+                            declared, vk.name(), vk.typeName(), value);
+                    concise("%s : %s", vk.name(), value);
+                }
+                break;
+            }
+            case TEMP_VAR_EXPRESSION_SUBKIND: {
+                VarSnippet vk = (VarSnippet) key;
+                if (update) {
+                    hard("%s temporary variable %s, reset to null", declared, vk.name());
+                 } else {
+                    fluff("Expression value is: %s", (value));
+                    fluff("  assigned to temporary variable %s of type %s", vk.name(), vk.typeName());
+                    concise("%s : %s", vk.name(), value);
+                }
+                break;
+            }
+            case OTHER_EXPRESSION_SUBKIND:
+                fluff("Expression value is: %s", (value));
+                break;
+            case VAR_VALUE_SUBKIND: {
+                ExpressionSnippet ek = (ExpressionSnippet) key;
+                fluff("Variable %s of type %s has value %s", ek.name(), ek.typeName(), (value));
+                concise("%s : %s", ek.name(), value);
+                break;
+            }
+            case ASSIGNMENT_SUBKIND: {
+                ExpressionSnippet ek = (ExpressionSnippet) key;
+                fluff("Variable %s has been assigned the value %s", ek.name(), (value));
+                concise("%s : %s", ek.name(), value);
+                break;
+            }
+        }
+    }
+    //where
+    void printStackTrace(StackTraceElement[] stes) {
+        for (StackTraceElement ste : stes) {
+            StringBuilder sb = new StringBuilder();
+            String cn = ste.getClassName();
+            if (!cn.isEmpty()) {
+                int dot = cn.lastIndexOf('.');
+                if (dot > 0) {
+                    sb.append(cn.substring(dot + 1));
+                } else {
+                    sb.append(cn);
+                }
+                sb.append(".");
+            }
+            if (!ste.getMethodName().isEmpty()) {
+                sb.append(ste.getMethodName());
+                sb.append(" ");
+            }
+            String fileName = ste.getFileName();
+            int lineNumber = ste.getLineNumber();
+            String loc = ste.isNativeMethod()
+                    ? "Native Method"
+                    : fileName == null
+                            ? "Unknown Source"
+                            : lineNumber >= 0
+                                    ? fileName + ":" + lineNumber
+                                    : fileName;
+            hard("      at %s(%s)", sb, loc);
+
+        }
+    }
+    //where
+    void printUnresolved(UnresolvedReferenceException ex) {
+        MethodSnippet corralled =  ex.getMethodSnippet();
+        List<Diag> otherErrors = errorsOnly(state.diagnostics(corralled));
+        StringBuilder sb = new StringBuilder();
+        if (otherErrors.size() > 0) {
+            if (state.unresolvedDependencies(corralled).size() > 0) {
+                sb.append(" and");
+            }
+            if (otherErrors.size() == 1) {
+                sb.append(" this error is addressed --");
+            } else {
+                sb.append(" these errors are addressed --");
+            }
+        } else {
+            sb.append(".");
+        }
+
+        hard("Attempted to call %s which cannot be invoked until%s", corralled.name(),
+                unresolved(corralled), sb.toString());
+        if (otherErrors.size() > 0) {
+            printDiagnostics(corralled.source(), otherErrors, true);
+        }
+    }
+    //where
+    void printEvalException(EvalException ex) {
+        if (ex.getMessage() == null) {
+            hard("%s thrown", ex.getExceptionClassName());
+        } else {
+            hard("%s thrown: %s", ex.getExceptionClassName(), ex.getMessage());
+        }
+        printStackTrace(ex.getStackTrace());
+    }
+    //where
+    String unresolved(DeclarationSnippet key) {
+        List<String> unr = state.unresolvedDependencies(key);
+        StringBuilder sb = new StringBuilder();
+        int fromLast = unr.size();
+        if (fromLast > 0) {
+            sb.append(" ");
+        }
+        for (String u : unr) {
+            --fromLast;
+            sb.append(u);
+            if (fromLast == 0) {
+                // No suffix
+            } else if (fromLast == 1) {
+                sb.append(", and ");
+            } else {
+                sb.append(", ");
+            }
+        }
+        switch (unr.size()) {
+            case 0:
+                break;
+            case 1:
+                sb.append(" is declared");
+                break;
+            default:
+                sb.append(" are declared");
+                break;
+        }
+        return sb.toString();
+    }
+
+    enum Feedback {
+        Default,
+        Off,
+        Concise,
+        Normal,
+        Verbose
+    }
+
+    Feedback feedback() {
+        if (feedback == Feedback.Default) {
+            return input == null || input.interactiveOutput() ? Feedback.Normal : Feedback.Off;
+        }
+        return feedback;
+    }
+
+    boolean notInStartUp(Snippet sn) {
+        return mapSnippet.get(sn).space != startNamespace;
+    }
+
+    /** The current version number as a string.
+     */
+    static String version() {
+        return version("release");  // mm.nn.oo[-milestone]
+    }
+
+    /** The current full version number as a string.
+     */
+    static String fullVersion() {
+        return version("full"); // mm.mm.oo[-milestone]-build
+    }
+
+    private static final String versionRBName = "jdk.internal.jshell.tool.resources.version";
+    private static ResourceBundle versionRB;
+
+    private static String version(String key) {
+        if (versionRB == null) {
+            try {
+                versionRB = ResourceBundle.getBundle(versionRBName);
+            } catch (MissingResourceException e) {
+                return "(version info not available)";
+            }
+        }
+        try {
+            return versionRB.getString(key);
+        }
+        catch (MissingResourceException e) {
+            return "(version info not available)";
+        }
+    }
+
+    class NameSpace {
+        final String spaceName;
+        final String prefix;
+        private int nextNum;
+
+        NameSpace(String spaceName, String prefix) {
+            this.spaceName = spaceName;
+            this.prefix = prefix;
+            this.nextNum = 1;
+        }
+
+        String tid(Snippet sn) {
+            String tid = prefix + nextNum++;
+            mapSnippet.put(sn, new SnippetInfo(sn, this, tid));
+            return tid;
+        }
+
+        String tidNext() {
+            return prefix + nextNum;
+        }
+    }
+
+    static class SnippetInfo {
+        final Snippet snippet;
+        final NameSpace space;
+        final String tid;
+
+        SnippetInfo(Snippet snippet, NameSpace space, String tid) {
+            this.snippet = snippet;
+            this.space = space;
+            this.tid = tid;
+        }
+    }
+}
+
+class ScannerIOContext extends IOContext {
+
+    private final Scanner scannerIn;
+    private final PrintStream pStream;
+
+    public ScannerIOContext(Scanner scannerIn, PrintStream pStream) {
+        this.scannerIn = scannerIn;
+        this.pStream = pStream;
+    }
+
+    @Override
+    public String readLine(String prompt, String prefix) {
+        if (pStream != null && prompt != null) {
+            pStream.print(prompt);
+        }
+        if (scannerIn.hasNextLine()) {
+            return scannerIn.nextLine();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean interactiveOutput() {
+        return true;
+    }
+
+    @Override
+    public Iterable<String> currentSessionHistory() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void close() {
+        scannerIn.close();
+    }
+
+    @Override
+    public boolean terminalEditorRunning() {
+        return false;
+    }
+
+    @Override
+    public void suspend() {
+    }
+
+    @Override
+    public void resume() {
+    }
+
+    @Override
+    public void beforeUserCode() {
+    }
+
+    @Override
+    public void afterUserCode() {
+    }
+
+    @Override
+    public void replaceLastHistoryEntry(String source) {
+    }
+}
+
+class FileScannerIOContext extends ScannerIOContext {
+
+    public FileScannerIOContext(String fn) throws FileNotFoundException {
+        this(new FileReader(fn));
+    }
+
+    public FileScannerIOContext(Reader rdr) throws FileNotFoundException {
+        super(new Scanner(rdr), null);
+    }
+
+    @Override
+    public boolean interactiveOutput() {
+        return false;
+    }
+}
+
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java
new file mode 100644
index 0000000..1c3e186
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.jshell.tool;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.function.Consumer;
+
+public final class StopDetectingInputStream extends InputStream {
+    public static final int INITIAL_SIZE = 128;
+
+    private final Runnable stop;
+    private final Consumer<Exception> errorHandler;
+
+    private boolean initialized;
+    private int[] buffer = new int[INITIAL_SIZE];
+    private int start;
+    private int end;
+    private State state = State.WAIT;
+
+    public StopDetectingInputStream(Runnable stop, Consumer<Exception> errorHandler) {
+        this.stop = stop;
+        this.errorHandler = errorHandler;
+    }
+
+    public synchronized InputStream setInputStream(InputStream input) {
+        if (initialized)
+            throw new IllegalStateException("Already initialized.");
+        initialized = true;
+
+        Thread reader = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    int read;
+                    while (true) {
+                        //to support external terminal editors, the "cmdin.read" must not run when
+                        //an external editor is running. At the same time, it needs to run while the
+                        //user's code is running (so Ctrl-C is detected). Hence waiting here until
+                        //there is a confirmed need for input.
+                        waitInputNeeded();
+                        if ((read = input.read()) == (-1)) {
+                            break;
+                        }
+                        if (read == 3 && state == StopDetectingInputStream.State.BUFFER) {
+                            stop.run();
+                        } else {
+                            write(read);
+                        }
+                    }
+                } catch (IOException ex) {
+                    errorHandler.accept(ex);
+                } finally {
+                    state = StopDetectingInputStream.State.CLOSED;
+                }
+            }
+        };
+        reader.setDaemon(true);
+        reader.start();
+
+        return this;
+    }
+
+    @Override
+    public synchronized int read() {
+        while (start == end) {
+            if (state == State.CLOSED) {
+                return -1;
+            }
+            if (state == State.WAIT) {
+                state = State.READ;
+            }
+            notifyAll();
+            try {
+                wait();
+            } catch (InterruptedException ex) {
+                //ignore
+            }
+        }
+        try {
+            return buffer[start];
+        } finally {
+            start = (start + 1) % buffer.length;
+        }
+    }
+
+    public synchronized void write(int b) {
+        if (state != State.BUFFER) {
+            state = State.WAIT;
+        }
+        int newEnd = (end + 1) % buffer.length;
+        if (newEnd == start) {
+            //overflow:
+            int[] newBuffer = new int[buffer.length * 2];
+            int rightPart = (end > start ? end : buffer.length) - start;
+            int leftPart = end > start ? 0 : start - 1;
+            System.arraycopy(buffer, start, newBuffer, 0, rightPart);
+            System.arraycopy(buffer, 0, newBuffer, rightPart, leftPart);
+            buffer = newBuffer;
+            start = 0;
+            end = rightPart + leftPart;
+            newEnd = end + 1;
+        }
+        buffer[end] = b;
+        end = newEnd;
+        notifyAll();
+    }
+
+    public synchronized void setState(State state) {
+        this.state = state;
+        notifyAll();
+    }
+
+    private synchronized void waitInputNeeded() {
+        while (state == State.WAIT) {
+            try {
+                wait();
+            } catch (InterruptedException ex) {
+                //ignore
+            }
+        }
+    }
+
+    public enum State {
+        /* No reading from the input should happen. This is the default state. The StopDetectingInput
+         * must be in this state when an external editor is being run, so that the external editor
+         * can read from the input.
+         */
+        WAIT,
+        /* A single input character should be read. Reading from the StopDetectingInput will move it
+         * into this state, and the state will be automatically changed back to WAIT when a single
+         * input character is obtained. This state is typically used while the user is editing the
+         * input line.
+         */
+        READ,
+        /* Continuously read from the input. Forward Ctrl-C ((int) 3) to the "stop" Runnable, buffer
+         * all other input. This state is typically used while the user's code is running, to provide
+         * the ability to detect Ctrl-C in order to stop the execution.
+         */
+        BUFFER,
+        /* The input is closed.
+        */
+        CLOSED
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/version.properties-template b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/version.properties-template
new file mode 100644
index 0000000..c372372
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/version.properties-template
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# 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.
+#
+
+jdk=$(JDK_VERSION)
+full=$(FULL_VERSION)
+release=$(RELEASE)
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java
new file mode 100644
index 0000000..206aa94
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import com.sun.jdi.ReferenceType;
+
+/**
+ * Tracks the state of a class through compilation and loading in the remote
+ * environment.
+ *
+ * @author Robert Field
+ */
+class ClassTracker {
+
+    private final JShell state;
+    private final HashMap<String, ClassInfo> map;
+
+    ClassTracker(JShell state) {
+        this.state = state;
+        this.map = new HashMap<>();
+    }
+
+    class ClassInfo {
+
+        private final String className;
+        private byte[] bytes;
+        private byte[] loadedBytes;
+        private ReferenceType rt;
+
+        private ClassInfo(String className) {
+            this.className = className;
+        }
+
+        String getClassName() {
+            return className;
+        }
+
+        byte[] getBytes() {
+            return bytes;
+        }
+
+        void setBytes(byte[] bytes) {
+            this.bytes = bytes;
+        }
+
+        void setLoaded() {
+            loadedBytes = bytes;
+        }
+
+        boolean isLoaded() {
+            return Arrays.equals(loadedBytes, bytes);
+        }
+
+        ReferenceType getReferenceTypeOrNull() {
+            if (rt == null) {
+                rt = state.executionControl().nameToRef(className);
+            }
+            return rt;
+        }
+    }
+
+    ClassInfo classInfo(String className, byte[] bytes) {
+        ClassInfo ci = map.computeIfAbsent(className, k -> new ClassInfo(k));
+        ci.setBytes(bytes);
+        return ci;
+    }
+
+    ClassInfo get(String className) {
+        return map.get(className);
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java
new file mode 100644
index 0000000..462d61e
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java
@@ -0,0 +1,885 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.parser.Scanner;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.parser.Tokens.Token;
+import com.sun.tools.javac.parser.Tokens.TokenKind;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.Log;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.EnumMap;
+import java.util.Iterator;
+import jdk.jshell.SourceCodeAnalysis.Completeness;
+import com.sun.source.tree.Tree;
+import static jdk.jshell.CompletenessAnalyzer.TK.*;
+import jdk.jshell.TaskFactory.ParseTask;
+import java.util.List;
+
+/**
+ * Low level scanner to determine completeness of input.
+ * @author Robert Field
+ */
+class CompletenessAnalyzer {
+
+    private final ScannerFactory scannerFactory;
+    private final JShell proc;
+
+    private static Completeness error() {
+        return Completeness.UNKNOWN;  // For breakpointing
+    }
+
+    static class CaInfo {
+
+        CaInfo(Completeness status, int unitEndPos) {
+            this.status = status;
+            this.unitEndPos = unitEndPos;
+        }
+        final int unitEndPos;
+        final Completeness status;
+    }
+
+    CompletenessAnalyzer(JShell proc) {
+        this.proc = proc;
+        Context context = new Context();
+        Log log = CaLog.createLog(context);
+        context.put(Log.class, log);
+        context.put(Source.class, Source.JDK1_9);
+        scannerFactory = ScannerFactory.instance(context);
+    }
+
+    CaInfo scan(String s) {
+        try {
+            Scanner scanner = scannerFactory.newScanner(s, false);
+            Matched in = new Matched(scanner);
+            Parser parser = new Parser(in, proc, s);
+            Completeness stat = parser.parseUnit();
+            int endPos = stat == Completeness.UNKNOWN
+                    ? s.length()
+                    : in.prevCT.endPos;
+            return new CaInfo(stat, endPos);
+        } catch (SyntaxException ex) {
+            return new CaInfo(error(), s.length());
+        }
+    }
+
+    @SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+    private static class SyntaxException extends RuntimeException {
+    }
+
+    private static void die() {
+        throw new SyntaxException();
+    }
+
+    /**
+     * Subclass of Log used by compiler API to die on error and ignore
+     * other messages
+     */
+    private static class CaLog extends Log {
+
+        private static CaLog createLog(Context context) {
+            PrintWriter pw = new PrintWriter(new StringWriter());
+            CaLog log = new CaLog(context, pw, pw, pw);
+            context.put(outKey, pw);
+            context.put(logKey, log);
+            return log;
+        }
+
+        private CaLog(Context context, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter) {
+            super(context, errWriter, warnWriter, noticeWriter);
+        }
+
+        @Override
+        public void error(String key, Object... args) {
+            die();
+        }
+
+        @Override
+        public void error(DiagnosticPosition pos, String key, Object... args) {
+            die();
+        }
+
+        @Override
+        public void error(DiagnosticFlag flag, DiagnosticPosition pos, String key, Object... args) {
+            die();
+        }
+
+        @Override
+        public void error(int pos, String key, Object... args) {
+            die();
+        }
+
+        @Override
+        public void error(DiagnosticFlag flag, int pos, String key, Object... args) {
+            die();
+        }
+
+        @Override
+        public void report(JCDiagnostic diagnostic) {
+            // Ignore
+        }
+    }
+
+    // Location position kinds -- a token is ...
+    private static final int XEXPR         = 0b1;                       // OK in expression (not first)
+    private static final int XDECL         = 0b10;                      // OK in declaration (not first)
+    private static final int XSTMT         = 0b100;                     // OK in statement framework (not first)
+    private static final int XEXPR1o       = 0b1000;                    // OK first in expression
+    private static final int XDECL1o       = 0b10000;                   // OK first in declaration
+    private static final int XSTMT1o       = 0b100000;                  // OK first or only in statement framework
+    private static final int XEXPR1        = XEXPR1o | XEXPR;           // OK in expression (anywhere)
+    private static final int XDECL1        = XDECL1o | XDECL;           // OK in declaration (anywhere)
+    private static final int XSTMT1        = XSTMT1o | XSTMT;           // OK in statement framework (anywhere)
+    private static final int XANY1         = XEXPR1o | XDECL1o | XSTMT1o;  // Mask: first in statement, declaration, or expression
+    private static final int XTERM         = 0b100000000;               // Can terminate (last before EOF)
+    private static final int XSTART        = 0b1000000000;              // Boundary, must be XTERM before
+    private static final int XERRO         = 0b10000000000;             // Is an error
+
+    /**
+     * An extension of the compiler's TokenKind which adds our combined/processed
+     * kinds. Also associates each TK with a union of acceptable kinds of code
+     * position it can occupy.  For example: IDENTIFER is XEXPR1|XDECL1|XTERM,
+     * meaning it can occur in expressions or declarations (but not in the
+     * framework of a statement and that can be the final (terminating) token
+     * in a snippet.
+     * <P>
+     * There must be a TK defined for each compiler TokenKind, an exception
+     * will
+     * be thrown if a TokenKind is defined and a corresponding TK is not. Add a
+     * new TK in the appropriate category. If it is like an existing category
+     * (e.g. a new modifier or type this may be all that is needed.  If it
+     * is bracketing or modifies the acceptable positions of other tokens,
+     * please closely examine the needed changes to this scanner.
+     */
+    static enum TK {
+
+        // Special
+        EOF(TokenKind.EOF, 0),  //
+        ERROR(TokenKind.ERROR, XERRO),  //
+        IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM),  //
+        UNDERSCORE(TokenKind.UNDERSCORE, XERRO),  //  _
+        CLASS(TokenKind.CLASS, XEXPR|XDECL1|XTERM),  //  class decl and .class
+        MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1),  //  @
+        IMPORT(TokenKind.IMPORT, XDECL1|XSTART),  //  import -- consider declaration
+        SEMI(TokenKind.SEMI, XSTMT1|XTERM|XSTART),  //  ;
+
+        // Shouldn't see -- error
+        PACKAGE(TokenKind.PACKAGE, XERRO),  //  package
+        CONST(TokenKind.CONST, XERRO),  //  reserved keyword -- const
+        GOTO(TokenKind.GOTO, XERRO),  //  reserved keyword -- goto
+        CUSTOM(TokenKind.CUSTOM, XERRO),  // No uses
+
+        // Declarations
+        ENUM(TokenKind.ENUM, XDECL1),  //  enum
+        IMPLEMENTS(TokenKind.IMPLEMENTS, XDECL),  //  implements
+        INTERFACE(TokenKind.INTERFACE, XDECL1),  //  interface
+        THROWS(TokenKind.THROWS, XDECL),  //  throws
+
+        // Primarive type names
+        BOOLEAN(TokenKind.BOOLEAN, XEXPR|XDECL1),  //  boolean
+        BYTE(TokenKind.BYTE, XEXPR|XDECL1),  //  byte
+        CHAR(TokenKind.CHAR, XEXPR|XDECL1),  //  char
+        DOUBLE(TokenKind.DOUBLE, XEXPR|XDECL1),  //  double
+        FLOAT(TokenKind.FLOAT, XEXPR|XDECL1),  //  float
+        INT(TokenKind.INT, XEXPR|XDECL1),  //  int
+        LONG(TokenKind.LONG, XEXPR|XDECL1),  //  long
+        SHORT(TokenKind.SHORT, XEXPR|XDECL1),  //  short
+        VOID(TokenKind.VOID, XEXPR|XDECL1),  //  void
+
+        // Modifiers keywords
+        ABSTRACT(TokenKind.ABSTRACT, XDECL1),  //  abstract
+        FINAL(TokenKind.FINAL, XDECL1),  //  final
+        NATIVE(TokenKind.NATIVE, XDECL1),  //  native
+        STATIC(TokenKind.STATIC, XDECL1),  //  static
+        STRICTFP(TokenKind.STRICTFP, XDECL1),  //  strictfp
+        PRIVATE(TokenKind.PRIVATE, XDECL1),  //  private
+        PROTECTED(TokenKind.PROTECTED, XDECL1),  //  protected
+        PUBLIC(TokenKind.PUBLIC, XDECL1),  //  public
+        TRANSIENT(TokenKind.TRANSIENT, XDECL1),  //  transient
+        VOLATILE(TokenKind.VOLATILE, XDECL1),  //  volatile
+
+        // Declarations and type parameters (thus expressions)
+        EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL),  //  extends
+        COMMA(TokenKind.COMMA, XEXPR|XDECL|XSTART),  //  ,
+        AMP(TokenKind.AMP, XEXPR|XDECL),  //  &
+        GT(TokenKind.GT, XEXPR|XDECL),  //  >
+        LT(TokenKind.LT, XEXPR|XDECL1),  //  <
+        LTLT(TokenKind.LTLT, XEXPR|XDECL1),  //  <<
+        GTGT(TokenKind.GTGT, XEXPR|XDECL),  //  >>
+        GTGTGT(TokenKind.GTGTGT, XEXPR|XDECL),  //  >>>
+        QUES(TokenKind.QUES, XEXPR|XDECL),  //  ?
+        DOT(TokenKind.DOT, XEXPR|XDECL),  //  .
+        STAR(TokenKind.STAR, XEXPR|XDECL|XTERM),  //  * -- import foo.* //TODO handle these case separately, XTERM
+
+        // Statement keywords
+        ASSERT(TokenKind.ASSERT, XSTMT1|XSTART),  //  assert
+        BREAK(TokenKind.BREAK, XSTMT1|XTERM|XSTART),  //  break
+        CATCH(TokenKind.CATCH, XSTMT1|XSTART),  //  catch
+        CONTINUE(TokenKind.CONTINUE, XSTMT1|XTERM|XSTART),  //  continue
+        DO(TokenKind.DO, XSTMT1|XSTART),  //  do
+        ELSE(TokenKind.ELSE, XSTMT1|XTERM|XSTART),  //  else
+        FINALLY(TokenKind.FINALLY, XSTMT1|XSTART),  //  finally
+        FOR(TokenKind.FOR, XSTMT1|XSTART),  //  for
+        IF(TokenKind.IF, XSTMT1|XSTART),  //  if
+        RETURN(TokenKind.RETURN, XSTMT1|XTERM|XSTART),  //  return
+        SWITCH(TokenKind.SWITCH, XSTMT1|XSTART),  //  switch
+        SYNCHRONIZED(TokenKind.SYNCHRONIZED, XSTMT1|XDECL),  //  synchronized
+        THROW(TokenKind.THROW, XSTMT1|XSTART),  //  throw
+        TRY(TokenKind.TRY, XSTMT1|XSTART),  //  try
+        WHILE(TokenKind.WHILE, XSTMT1|XSTART),  //  while
+
+        // Statement keywords that we shouldn't see -- inside braces
+        CASE(TokenKind.CASE, XSTMT|XSTART),  //  case
+        DEFAULT(TokenKind.DEFAULT, XSTMT|XSTART),  //  default method, default case -- neither we should see
+
+        // Expressions (can terminate)
+        INTLITERAL(TokenKind.INTLITERAL, XEXPR1|XTERM),  //
+        LONGLITERAL(TokenKind.LONGLITERAL, XEXPR1|XTERM),  //
+        FLOATLITERAL(TokenKind.FLOATLITERAL, XEXPR1|XTERM),  //
+        DOUBLELITERAL(TokenKind.DOUBLELITERAL, XEXPR1|XTERM),  //
+        CHARLITERAL(TokenKind.CHARLITERAL, XEXPR1|XTERM),  //
+        STRINGLITERAL(TokenKind.STRINGLITERAL, XEXPR1|XTERM),  //
+        TRUE(TokenKind.TRUE, XEXPR1|XTERM),  //  true
+        FALSE(TokenKind.FALSE, XEXPR1|XTERM),  //  false
+        NULL(TokenKind.NULL, XEXPR1|XTERM),  //  null
+        THIS(TokenKind.THIS, XEXPR1|XTERM),  //  this  -- shouldn't see
+
+        // Expressions maybe terminate  //TODO handle these case separately
+        PLUSPLUS(TokenKind.PLUSPLUS, XEXPR1|XTERM),  //  ++
+        SUBSUB(TokenKind.SUBSUB, XEXPR1|XTERM),  //  --
+
+        // Expressions cannot terminate
+        INSTANCEOF(TokenKind.INSTANCEOF, XEXPR),  //  instanceof
+        NEW(TokenKind.NEW, XEXPR1),  //  new
+        SUPER(TokenKind.SUPER, XEXPR1|XDECL),  //  super -- shouldn't see as rec. But in type parameters
+        ARROW(TokenKind.ARROW, XEXPR),  //  ->
+        COLCOL(TokenKind.COLCOL, XEXPR),  //  ::
+        LPAREN(TokenKind.LPAREN, XEXPR),  //  (
+        RPAREN(TokenKind.RPAREN, XEXPR),  //  )
+        LBRACE(TokenKind.LBRACE, XEXPR),  //  {
+        RBRACE(TokenKind.RBRACE, XEXPR),  //  }
+        LBRACKET(TokenKind.LBRACKET, XEXPR),  //  [
+        RBRACKET(TokenKind.RBRACKET, XEXPR),  //  ]
+        ELLIPSIS(TokenKind.ELLIPSIS, XEXPR),  //  ...
+        EQ(TokenKind.EQ, XEXPR),  //  =
+        BANG(TokenKind.BANG, XEXPR1),  //  !
+        TILDE(TokenKind.TILDE, XEXPR1),  //  ~
+        COLON(TokenKind.COLON, XEXPR|XTERM),  //  :
+        EQEQ(TokenKind.EQEQ, XEXPR),  //  ==
+        LTEQ(TokenKind.LTEQ, XEXPR),  //  <=
+        GTEQ(TokenKind.GTEQ, XEXPR),  //  >=
+        BANGEQ(TokenKind.BANGEQ, XEXPR),  //  !=
+        AMPAMP(TokenKind.AMPAMP, XEXPR),  //  &&
+        BARBAR(TokenKind.BARBAR, XEXPR),  //  ||
+        PLUS(TokenKind.PLUS, XEXPR1),  //  +
+        SUB(TokenKind.SUB, XEXPR1),  //  -
+        SLASH(TokenKind.SLASH, XEXPR),  //  /
+        BAR(TokenKind.BAR, XEXPR),  //  |
+        CARET(TokenKind.CARET, XEXPR),  //  ^
+        PERCENT(TokenKind.PERCENT, XEXPR),  //  %
+        PLUSEQ(TokenKind.PLUSEQ, XEXPR),  //  +=
+        SUBEQ(TokenKind.SUBEQ, XEXPR),  //  -=
+        STAREQ(TokenKind.STAREQ, XEXPR),  //  *=
+        SLASHEQ(TokenKind.SLASHEQ, XEXPR),  //  /=
+        AMPEQ(TokenKind.AMPEQ, XEXPR),  //  &=
+        BAREQ(TokenKind.BAREQ, XEXPR),  //  |=
+        CARETEQ(TokenKind.CARETEQ, XEXPR),  //  ^=
+        PERCENTEQ(TokenKind.PERCENTEQ, XEXPR),  //  %=
+        LTLTEQ(TokenKind.LTLTEQ, XEXPR),  //  <<=
+        GTGTEQ(TokenKind.GTGTEQ, XEXPR),  //  >>=
+        GTGTGTEQ(TokenKind.GTGTGTEQ, XEXPR),  //  >>>=
+
+        // combined/processed kinds
+        UNMATCHED(XERRO),
+        PARENS(XEXPR1|XDECL|XSTMT|XTERM),
+        BRACKETS(XEXPR|XDECL|XTERM),
+        BRACES(XSTMT1|XEXPR|XTERM);
+
+        static final EnumMap<TokenKind,TK> tokenKindToTKMap = new EnumMap<>(TokenKind.class);
+
+        final TokenKind tokenKind;
+        final int belongs;
+
+        TK(int b) {
+            this.tokenKind = null;
+            this.belongs = b;
+        }
+
+        TK(TokenKind tokenKind, int b) {
+            this.tokenKind = tokenKind;
+            this.belongs = b;
+        }
+
+        private static TK tokenKindToTK(TokenKind kind) {
+            TK tk = tokenKindToTKMap.get(kind);
+            if (tk == null) {
+                System.err.printf("No corresponding %s for %s: %s\n",
+                        TK.class.getCanonicalName(),
+                        TokenKind.class.getCanonicalName(),
+                        kind);
+                throw new InternalError("No corresponding TK for TokenKind: " + kind);
+            }
+            return tk;
+        }
+
+        boolean isOkToTerminate() {
+            return (belongs & XTERM) != 0;
+        }
+
+        boolean isExpression() {
+            return (belongs & XEXPR) != 0;
+        }
+
+        boolean isDeclaration() {
+            return (belongs & XDECL) != 0;
+        }
+
+        boolean isError() {
+            return (belongs & XERRO) != 0;
+        }
+
+        boolean isStart() {
+            return (belongs & XSTART) != 0;
+        }
+
+        /**
+         * After construction, check that all compiler TokenKind values have
+         * corresponding TK values.
+         */
+        static {
+            for (TK tk : TK.values()) {
+                if (tk.tokenKind != null) {
+                    tokenKindToTKMap.put(tk.tokenKind, tk);
+                }
+            }
+            for (TokenKind kind : TokenKind.values()) {
+                tokenKindToTK(kind); // assure they can be retrieved without error
+            }
+        }
+    }
+
+    /**
+     * A completeness scanner token.
+     */
+    private static class CT {
+
+        /** The token kind */
+        public final TK kind;
+
+        /** The end position of this token */
+        public final int endPos;
+
+        /** The error message **/
+        public final String message;
+
+        private CT(TK tk, Token tok, String msg) {
+            this.kind = tk;
+            this.endPos = tok.endPos;
+            this.message = msg;
+            //throw new InternalError(msg); /* for debugging */
+        }
+
+        private CT(TK tk, Token tok) {
+            this.kind = tk;
+            this.endPos = tok.endPos;
+            this.message = null;
+        }
+
+        private CT(TK tk, int endPos) {
+            this.kind = tk;
+            this.endPos = endPos;
+            this.message = null;
+        }
+    }
+
+    /**
+     * Look for matching tokens (like parens) and other special cases, like "new"
+     */
+    private static class Matched implements Iterator<CT> {
+
+        private final Scanner scanner;
+        private Token current;
+        private CT prevCT;
+        private CT currentCT;
+        private final Deque<Token> stack = new ArrayDeque<>();
+
+        Matched(Scanner scanner) {
+            this.scanner = scanner;
+            advance();
+            prevCT = currentCT = new CT(SEMI, 0); // So is valid for testing
+        }
+
+        @Override
+        public boolean hasNext() {
+            return currentCT.kind != EOF;
+        }
+
+        private Token advance() {
+            Token prev = current;
+            scanner.nextToken();
+            current = scanner.token();
+            return prev;
+        }
+
+        @Override
+        public CT next() {
+            prevCT = currentCT;
+            currentCT = nextCT();
+            return currentCT;
+        }
+
+        private CT match(TK tk, TokenKind open) {
+            Token tok = advance();
+            db("match desired-tk=%s, open=%s, seen-tok=%s", tk, open, tok.kind);
+            if (stack.isEmpty()) {
+                return new CT(ERROR, tok, "Encountered '" + tok + "' with no opening '" + open + "'");
+            }
+            Token p = stack.pop();
+            if (p.kind != open) {
+                return new CT(ERROR, tok, "No match for '" + p + "' instead encountered '" + tok + "'");
+            }
+            return new CT(tk, tok);
+        }
+
+        private void db(String format, Object ... args) {
+//            System.err.printf(format, args);
+//            System.err.printf(" -- stack(");
+//            if (stack.isEmpty()) {
+//
+//            } else {
+//                for (Token tok : stack) {
+//                    System.err.printf("%s ", tok.kind);
+//                }
+//            }
+//            System.err.printf(") current=%s / currentCT=%s\n", current.kind, currentCT.kind);
+        }
+
+        /**
+         * @return the next scanner token
+         */
+        private CT nextCT() {
+            // TODO Annotations?
+            TK prevTK = currentCT.kind;
+            while (true) {
+                db("nextCT");
+                CT ct;
+                switch (current.kind) {
+                    case EOF:
+                        db("eof");
+                        if (stack.isEmpty()) {
+                            ct = new CT(EOF, current);
+                        } else {
+                            TokenKind unmatched = stack.pop().kind;
+                            stack.clear(); // So we will get EOF next time
+                            ct = new CT(UNMATCHED, current, "Unmatched " + unmatched);
+                        }
+                        break;
+                    case LPAREN:
+                    case LBRACE:
+                    case LBRACKET:
+                        stack.push(advance());
+                        prevTK = SEMI; // new start
+                        continue;
+                    case RPAREN:
+                        ct = match(PARENS, TokenKind.LPAREN);
+                        break;
+                    case RBRACE:
+                        ct = match(BRACES, TokenKind.LBRACE);
+                        break;
+                    case RBRACKET:
+                        ct = match(BRACKETS, TokenKind.LBRACKET);
+                        break;
+                    default:
+                        ct = new CT(TK.tokenKindToTK(current.kind), advance());
+                        break;
+                }
+                if (ct.kind.isStart() && !prevTK.isOkToTerminate()) {
+                    return new CT(ERROR, current, "No '" + prevTK + "' before '" + ct.kind + "'");
+                }
+                if (stack.isEmpty() || ct.kind.isError()) {
+                    return ct;
+                }
+                prevTK = ct.kind;
+            }
+        }
+    }
+
+    /**
+     * Fuzzy parser based on token kinds
+     */
+    private static class Parser {
+
+        final Matched in;
+        CT token;
+        Completeness checkResult;
+
+        final JShell proc;
+        final String scannedInput;
+
+
+
+        Parser(Matched in, JShell proc, String scannedInput) {
+            this.in = in;
+            nextToken();
+
+            this.proc = proc;
+            this.scannedInput = scannedInput;
+        }
+
+        final void nextToken() {
+            in.next();
+            token = in.currentCT;
+        }
+
+        boolean shouldAbort(TK tk) {
+            if (token.kind == tk) {
+                nextToken();
+                return false;
+            }
+            switch (token.kind) {
+                case EOF:
+                    checkResult = ((tk == SEMI) && in.prevCT.kind.isOkToTerminate())
+                            ? Completeness.COMPLETE_WITH_SEMI
+                            : Completeness.DEFINITELY_INCOMPLETE;
+                    return true;
+                case UNMATCHED:
+                    checkResult = Completeness.DEFINITELY_INCOMPLETE;
+                    return true;
+                default:
+                    checkResult = error();
+                    return true;
+
+            }
+        }
+
+        Completeness lastly(TK tk) {
+            if (shouldAbort(tk))  return checkResult;
+            return Completeness.COMPLETE;
+        }
+
+        Completeness optionalFinalSemi() {
+            if (!shouldAbort(SEMI)) return Completeness.COMPLETE;
+            if (checkResult == Completeness.COMPLETE_WITH_SEMI) return Completeness.COMPLETE;
+            return checkResult;
+        }
+
+        boolean shouldAbort(Completeness flags) {
+            checkResult = flags;
+            return flags != Completeness.COMPLETE;
+        }
+
+        public Completeness parseUnit() {
+            //System.err.printf("%s:  belongs %o  XANY1 %o\n", token.kind, token.kind.belongs, token.kind.belongs & XANY1);
+            switch (token.kind.belongs & XANY1) {
+                case XEXPR1o:
+                    return parseExpressionOptionalSemi();
+                case XSTMT1o: {
+                    Completeness stat = parseSimpleStatement();
+                    return stat==null? error() : stat;
+                }
+                case XDECL1o:
+                    return parseDeclaration();
+                case XSTMT1o | XDECL1o:
+                case XEXPR1o | XDECL1o:
+                    return disambiguateDeclarationVsExpression();
+                case 0:
+                    if ((token.kind.belongs & XERRO) != 0) {
+                        return parseExpressionStatement(); // Let this gen the status
+                    }
+                    return error();
+                default:
+                    throw new InternalError("Case not covered " + token.kind.belongs + " in " + token.kind);
+            }
+        }
+
+        public Completeness parseDeclaration() {
+            boolean isImport = token.kind == IMPORT;
+            while (token.kind.isDeclaration()) {
+                nextToken();
+            }
+            switch (token.kind) {
+                case EQ:
+                    // Check for array initializer
+                    nextToken();
+                    if (token.kind == BRACES) {
+                        nextToken();
+                        return lastly(SEMI);
+                    }
+                    return parseExpressionStatement();
+                case BRACES:
+                case SEMI:
+                    nextToken();
+                    return Completeness.COMPLETE;
+                case UNMATCHED:
+                    nextToken();
+                    return Completeness.DEFINITELY_INCOMPLETE;
+                case EOF:
+                    switch (in.prevCT.kind) {
+                        case BRACES:
+                        case SEMI:
+                            return Completeness.COMPLETE;
+                        case IDENTIFIER:
+                        case BRACKETS:
+                            return Completeness.COMPLETE_WITH_SEMI;
+                        case STAR:
+                            if (isImport) {
+                                return Completeness.COMPLETE_WITH_SEMI;
+                            } else {
+                                return Completeness.DEFINITELY_INCOMPLETE;
+                            }
+                        default:
+                            return Completeness.DEFINITELY_INCOMPLETE;
+                    }
+                default:
+                    return error();
+            }
+        }
+
+        public Completeness disambiguateDeclarationVsExpression() {
+            // String folding messes up position information.
+            ParseTask pt = proc.taskFactory.new ParseTask(scannedInput);
+            List<? extends Tree> units = pt.units();
+            if (units.isEmpty()) {
+                return error();
+            }
+            Tree unitTree = units.get(0);
+            switch (unitTree.getKind()) {
+                case EXPRESSION_STATEMENT:
+                    return parseExpressionOptionalSemi();
+                case LABELED_STATEMENT:
+                    if (shouldAbort(IDENTIFIER))  return checkResult;
+                    if (shouldAbort(COLON))  return checkResult;
+                    return parseStatement();
+                case VARIABLE:
+                case IMPORT:
+                case CLASS:
+                case ENUM:
+                case ANNOTATION_TYPE:
+                case INTERFACE:
+                case METHOD:
+                    return parseDeclaration();
+                default:
+                    return error();
+            }
+        }
+
+//        public Status parseExpressionOrDeclaration() {
+//            if (token.kind == IDENTIFIER) {
+//                nextToken();
+//                switch (token.kind) {
+//                    case IDENTIFIER:
+//                        return parseDeclaration();
+//                }
+//            }
+//            while (token.kind.isExpressionOrDeclaration()) {
+//                if (!token.kind.isExpression()) {
+//                    return parseDeclaration();
+//                }
+//                if (!token.kind.isDeclaration()) {
+//                    // Expression not declaration
+//                    if (token.kind == EQ) {
+//                        // Check for array initializer
+//                        nextToken();
+//                        if (token.kind == BRACES) {
+//                            nextToken();
+//                            return lastly(SEMI);
+//                        }
+//                    }
+//                    return parseExpressionStatement();
+//                }
+//                nextToken();
+//            }
+//            switch (token.kind) {
+//                case BRACES:
+//                case SEMI:
+//                    nextToken();
+//                    return Status.COMPLETE;
+//                case UNMATCHED:
+//                    nextToken();
+//                    return Status.DEFINITELY_INCOMPLETE;
+//                case EOF:
+//                    if (in.prevCT.kind.isOkToTerminate()) {
+//                        return Status.COMPLETE_WITH_SEMI;
+//                    } else {
+//                        return Status.DEFINITELY_INCOMPLETE;
+//                    }
+//                default:
+//                    return error();
+//            }
+//        }
+
+        public Completeness parseExpressionStatement() {
+            if (shouldAbort(parseExpression()))  return checkResult;
+            return lastly(SEMI);
+        }
+
+        public Completeness parseExpressionOptionalSemi() {
+            if (shouldAbort(parseExpression())) return checkResult;
+            return optionalFinalSemi();
+        }
+
+        public Completeness parseExpression() {
+            while (token.kind.isExpression())
+                nextToken();
+            return Completeness.COMPLETE;
+        }
+
+        public Completeness parseStatement() {
+            Completeness stat = parseSimpleStatement();
+            if (stat == null) {
+                return parseExpressionStatement();
+            }
+            return stat;
+        }
+
+        /**
+         * Statement = Block | IF ParExpression Statement [ELSE Statement] | FOR
+         * "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement | FOR
+         * "(" FormalParameter : Expression ")" Statement | WHILE ParExpression
+         * Statement | DO Statement WHILE ParExpression ";" | TRY Block (
+         * Catches | [Catches] FinallyPart ) | TRY "(" ResourceSpecification
+         * ";"opt ")" Block [Catches] [FinallyPart] | SWITCH ParExpression "{"
+         * SwitchBlockStatementGroups "}" | SYNCHRONIZED ParExpression Block |
+         * RETURN [Expression] ";" | THROW Expression ";" | BREAK [Ident] ";" |
+         * CONTINUE [Ident] ";" | ASSERT Expression [ ":" Expression ] ";" | ";"
+         */
+        public Completeness parseSimpleStatement() {
+            switch (token.kind) {
+                case BRACES:
+                    return lastly(BRACES);
+                case IF: {
+                    nextToken();
+                    if (shouldAbort(PARENS))  return checkResult;
+                    Completeness thenpart = parseStatement();
+                    if (shouldAbort(thenpart)) return thenpart;
+                    if (token.kind == ELSE) {
+                        nextToken();
+                        return parseStatement();
+                    }
+                    return thenpart;
+
+                }
+                case FOR: {
+                    nextToken();
+                    if (shouldAbort(PARENS))  return checkResult;
+                    if (shouldAbort(parseStatement()))  return checkResult;
+                    return Completeness.COMPLETE;
+                }
+                case WHILE: {
+                    nextToken();
+                    if (shouldAbort(PARENS))  return error();
+                    return parseStatement();
+                }
+                case DO: {
+                    nextToken();
+                    switch (parseStatement()) {
+                        case DEFINITELY_INCOMPLETE:
+                        case CONSIDERED_INCOMPLETE:
+                        case COMPLETE_WITH_SEMI:
+                            return Completeness.DEFINITELY_INCOMPLETE;
+                        case UNKNOWN:
+                            return error();
+                        case COMPLETE:
+                            break;
+                    }
+                    if (shouldAbort(WHILE))  return checkResult;
+                    if (shouldAbort(PARENS)) return checkResult;
+                    return lastly(SEMI);
+                }
+                case TRY: {
+                    boolean hasResources = false;
+                    nextToken();
+                    if (token.kind == PARENS) {
+                        nextToken();
+                        hasResources = true;
+                    }
+                    if (shouldAbort(BRACES))  return checkResult;
+                    if (token.kind == CATCH || token.kind == FINALLY) {
+                        while (token.kind == CATCH) {
+                            if (shouldAbort(CATCH))  return checkResult;
+                            if (shouldAbort(PARENS)) return checkResult;
+                            if (shouldAbort(BRACES)) return checkResult;
+                        }
+                        if (token.kind == FINALLY) {
+                            if (shouldAbort(FINALLY))  return checkResult;
+                            if (shouldAbort(BRACES)) return checkResult;
+                        }
+                    } else if (!hasResources) {
+                        if (token.kind == EOF) {
+                            return Completeness.DEFINITELY_INCOMPLETE;
+                        } else {
+                            return error();
+                        }
+                    }
+                    return Completeness.COMPLETE;
+                }
+                case SWITCH: {
+                    nextToken();
+                    if (shouldAbort(PARENS))  return checkResult;
+                    return lastly(BRACES);
+                }
+                case SYNCHRONIZED: {
+                    nextToken();
+                    if (shouldAbort(PARENS))  return checkResult;
+                    return lastly(BRACES);
+                }
+                case THROW: {
+                    nextToken();
+                    if (shouldAbort(parseExpression()))  return checkResult;
+                    return lastly(SEMI);
+                }
+                case SEMI:
+                    return lastly(SEMI);
+                case ASSERT:
+                    nextToken();
+                    // Crude expression parsing just happily eats the optional colon
+                    return parseExpressionStatement();
+                case RETURN:
+                case BREAK:
+                case CONTINUE:
+                    nextToken();
+                    return parseExpressionStatement();
+                // What are these doing here?
+                case ELSE:
+                case FINALLY:
+                case CATCH:
+                    return error();
+                case EOF:
+                    return Completeness.CONSIDERED_INCOMPLETE;
+                default:
+                    return null;
+            }
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java
new file mode 100644
index 0000000..c654964
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.Collection;
+import jdk.jshell.Key.DeclarationKey;
+
+/**
+ * Grouping for all declaration Snippets: variable declarations
+ * ({@link jdk.jshell.VarSnippet}), method declarations
+ * ({@link jdk.jshell.MethodSnippet}), and type declarations
+ * ({@link jdk.jshell.TypeDeclSnippet}).
+ * <p>
+ * Declaration snippets are unique in that they can be active
+ *  with unresolved references:
+ * {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED} or
+ * {@link jdk.jshell.Snippet.Status#RECOVERABLE_NOT_DEFINED RECOVERABLE_NOT_DEFINED}.
+ * Unresolved references can be queried with
+ * {@link jdk.jshell.JShell#unresolvedDependencies(jdk.jshell.DeclarationSnippet)
+ * JShell.unresolvedDependencies(DeclarationSnippet)}.
+ * <p>
+ * <code>DeclarationSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ */
+public abstract class DeclarationSnippet extends PersistentSnippet {
+
+    private final Wrap corralled;
+    private final Collection<String> declareReferences;
+    private final Collection<String> bodyReferences;
+
+    DeclarationSnippet(DeclarationKey key, String userSource, Wrap guts,
+            String unitName, SubKind subkind, Wrap corralled,
+            Collection<String> declareReferences,
+            Collection<String> bodyReferences) {
+        super(key, userSource, guts, unitName, subkind);
+        this.corralled = corralled;
+        this.declareReferences = declareReferences;
+        this.bodyReferences = bodyReferences;
+    }
+
+    /**** internal access ****/
+
+    /**
+     * @return the corralled guts
+     */
+    @Override
+    Wrap corralled() {
+        return corralled;
+    }
+
+    @Override
+    Collection<String> declareReferences() {
+        return declareReferences;
+    }
+
+    @Override
+    Collection<String> bodyReferences() {
+        return bodyReferences;
+    }
+
+    @Override
+    String importLine(JShell state) {
+        return "import static " + state.maps.classFullName(this) + "." + name() + ";\n";
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java
new file mode 100644
index 0000000..1139030
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.Locale;
+import javax.tools.Diagnostic;
+
+/**
+ * Diagnostic information for a Snippet.
+ * @see jdk.jshell.JShell#diagnostics(jdk.jshell.Snippet)
+ */
+public abstract class Diag {
+    // Simplified view on compiler Diagnostic.
+
+    /**
+     * Used to signal that no position is available.
+     */
+    public final static long NOPOS = Diagnostic.NOPOS;
+
+    /**
+     * Is this diagnostic and error (as opposed to a warning or note)
+     * @return true if this diagnostic is an error
+     */
+    public abstract boolean isError();
+
+    /**
+     * Returns a character offset from the beginning of the source object
+     * associated with this diagnostic that indicates the location of
+     * the problem.  In addition, the following must be true:
+     *
+     * <p>{@code getStartPostion() <= getPosition()}
+     * <p>{@code getPosition() <= getEndPosition()}
+     *
+     * @return character offset from beginning of source; {@link
+     * #NOPOS} if {@link #getSource()} would return {@code null} or if
+     * no location is suitable
+     */
+    public abstract long getPosition();
+
+    /**
+     * Returns the character offset from the beginning of the file
+     * associated with this diagnostic that indicates the start of the
+     * problem.
+     *
+     * @return offset from beginning of file; {@link #NOPOS} if and
+     * only if {@link #getPosition()} returns {@link #NOPOS}
+     */
+    public abstract long getStartPosition();
+
+    /**
+     * Returns the character offset from the beginning of the file
+     * associated with this diagnostic that indicates the end of the
+     * problem.
+     *
+     * @return offset from beginning of file; {@link #NOPOS} if and
+     * only if {@link #getPosition()} returns {@link #NOPOS}
+     */
+    public abstract long getEndPosition();
+
+    /**
+     * Returns a diagnostic code indicating the type of diagnostic.  The
+     * code is implementation-dependent and might be {@code null}.
+     *
+     * @return a diagnostic code
+     */
+    public abstract String getCode();
+
+    /**
+     * Returns a localized message for the given locale.  The actual
+     * message is implementation-dependent.  If the locale is {@code
+     * null} use the default locale.
+     *
+     * @param locale a locale; might be {@code null}
+     * @return a localized message
+     */
+    public abstract String getMessage(Locale locale);
+
+    // *** Internal support ***
+
+    /**
+     * Internal: If this is from a compile, extract the compilation Unit.
+     * Otherwise null.
+     */
+    abstract Unit unitOrNull();
+
+    /**
+     * This is an unreachable-statement error
+     */
+    boolean isUnreachableError() {
+        return getCode().equals("compiler.err.unreachable.stmt");
+    }
+
+    /**
+     * This is a not-a-statement error
+     */
+    boolean isNotAStatementError() {
+        return getCode().equals("compiler.err.not.stmt");
+    }
+
+    /**
+     * This is a resolution error.
+     */
+    boolean isResolutionError() {
+        //TODO: try javac RESOLVE_ERROR flag
+        return getCode().startsWith("compiler.err.cant.resolve");
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java
new file mode 100644
index 0000000..b0546fe
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DiagList.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * List of diagnostics, with convenient operations.
+ *
+ * @author Robert Field
+ */
+@SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+final class DiagList extends ArrayList<Diag> {
+
+    private int cntNotStmt = 0;
+    private int cntUnreach = 0;
+    private int cntResolve = 0;
+    private int cntOther = 0;
+
+    DiagList() {
+        super();
+    }
+
+    DiagList(Diag d) {
+        super();
+        add(d);
+    }
+
+    DiagList(Collection<? extends Diag> c) {
+        super();
+        addAll(c);
+    }
+
+    private void tally(Diag d) {
+        if (d.isError()) {
+            if (d.isUnreachableError()) {
+                ++cntUnreach;
+            } else if (d.isNotAStatementError()) {
+                ++cntNotStmt;
+            } else if (d.isResolutionError()) {
+                ++cntResolve;
+            } else {
+                ++cntOther;
+            }
+        }
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends Diag> c) {
+        return c.stream().filter(d -> add(d)).count() > 0;
+    }
+
+    @Override
+    public Diag set(int index, Diag element) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void add(int index, Diag element) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean add(Diag d) {
+        boolean added = super.add(d);
+        if (added) {
+            tally(d);
+        }
+        return added;
+    }
+
+    @Override
+    public boolean addAll(int index, Collection<? extends Diag> c) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        throw new UnsupportedOperationException();
+    }
+
+    DiagList ofUnit(Unit u) {
+        return this.stream()
+                .filter(d -> d.unitOrNull() == u)
+                .collect(Collectors.toCollection(() -> new DiagList()));
+    }
+
+    boolean hasErrors() {
+        return (cntNotStmt + cntResolve + cntUnreach + cntOther) > 0;
+    }
+
+    boolean hasResolutionErrorsAndNoOthers() {
+        return cntResolve > 0 && (cntNotStmt + cntUnreach + cntOther) == 0;
+    }
+
+    boolean hasUnreachableError() {
+        return cntUnreach > 0;
+    }
+
+    boolean hasNotStatement() {
+        return cntNotStmt > 0;
+    }
+
+    boolean hasOtherThanNotStatementErrors() {
+        return (cntResolve + cntUnreach + cntOther) > 0;
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ErroneousSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ErroneousSnippet.java
new file mode 100644
index 0000000..1a6ca62
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ErroneousSnippet.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import jdk.jshell.Key.ErroneousKey;
+
+/**
+ * A snippet of code that is not valid Java programming language code, and for
+ * which the kind of snippet could not be determined.
+ * The Kind is {@link jdk.jshell.Snippet.Kind#ERRONEOUS ERRONEOUS}.
+ * <p>
+ * <code>ErroneousSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ */
+public class ErroneousSnippet extends Snippet {
+
+    ErroneousSnippet(ErroneousKey key, String userSource, Wrap guts, SubKind subkind) {
+        super(key, userSource, guts, null, subkind);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java
new file mode 100644
index 0000000..212bb9e
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java
@@ -0,0 +1,730 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import javax.lang.model.element.Modifier;
+import com.sun.source.tree.ArrayTypeTree;
+import com.sun.source.tree.AssignmentTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.ModifiersTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.Pretty;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import jdk.jshell.ClassTracker.ClassInfo;
+import jdk.jshell.Key.ErroneousKey;
+import jdk.jshell.Key.MethodKey;
+import jdk.jshell.Snippet.SubKind;
+import jdk.jshell.TaskFactory.AnalyzeTask;
+import jdk.jshell.TaskFactory.BaseTask;
+import jdk.jshell.TaskFactory.CompileTask;
+import jdk.jshell.TaskFactory.ParseTask;
+import jdk.jshell.TreeDissector.ExpressionInfo;
+import jdk.jshell.Wrap.Range;
+import jdk.jshell.Snippet.Status;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import static jdk.jshell.Util.*;
+import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
+import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.TYPE_IMPORT_ON_DEMAND_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.STATIC_IMPORT_ON_DEMAND_SUBKIND;
+
+/**
+ * The Evaluation Engine. Source internal analysis, wrapping control,
+ * compilation, declaration. redefinition, replacement, and execution.
+ *
+ * @author Robert Field
+ */
+class Eval {
+
+    private static final Pattern IMPORT_PATTERN = Pattern.compile("import\\p{javaWhitespace}+(?<static>static\\p{javaWhitespace}+)?(?<fullname>[\\p{L}\\p{N}_\\$\\.]+\\.(?<name>[\\p{L}\\p{N}_\\$]+|\\*))");
+
+    private int varNumber = 0;
+
+    private final JShell state;
+
+    Eval(JShell state) {
+        this.state = state;
+    }
+
+    List<SnippetEvent> eval(String userSource) throws IllegalStateException {
+        String compileSource = Util.trimEnd(new MaskCommentsAndModifiers(userSource, false).cleared());
+        if (compileSource.length() == 0) {
+            return Collections.emptyList();
+        }
+        // String folding messes up position information.
+        ParseTask pt = state.taskFactory.new ParseTask(compileSource);
+        if (pt.getDiagnostics().hasOtherThanNotStatementErrors()) {
+            return compileFailResult(pt, userSource);
+        }
+
+        List<? extends Tree> units = pt.units();
+        if (units.isEmpty()) {
+            return compileFailResult(pt, userSource);
+        }
+        // Erase illegal modifiers
+        compileSource = new MaskCommentsAndModifiers(compileSource, true).cleared();
+        Tree unitTree = units.get(0);
+        state.debug(DBG_GEN, "Kind: %s -- %s\n", unitTree.getKind(), unitTree);
+        switch (unitTree.getKind()) {
+            case IMPORT:
+                return processImport(userSource, compileSource);
+            case VARIABLE:
+                return processVariables(userSource, units, compileSource, pt);
+            case EXPRESSION_STATEMENT:
+                return processExpression(userSource, compileSource);
+            case CLASS:
+                return processClass(userSource, unitTree, compileSource, SubKind.CLASS_SUBKIND, pt);
+            case ENUM:
+                return processClass(userSource, unitTree, compileSource, SubKind.ENUM_SUBKIND, pt);
+            case ANNOTATION_TYPE:
+                return processClass(userSource, unitTree, compileSource, SubKind.ANNOTATION_TYPE_SUBKIND, pt);
+            case INTERFACE:
+                return processClass(userSource, unitTree, compileSource, SubKind.INTERFACE_SUBKIND, pt);
+            case METHOD:
+                return processMethod(userSource, unitTree, compileSource, pt);
+            default:
+                return processStatement(userSource, compileSource);
+        }
+    }
+
+    private List<SnippetEvent> processImport(String userSource, String compileSource) {
+        Wrap guts = Wrap.importWrap(compileSource);
+        Matcher mat = IMPORT_PATTERN.matcher(compileSource);
+        String fullname;
+        String name;
+        boolean isStatic;
+        if (mat.find()) {
+            isStatic = mat.group("static") != null;
+            name = mat.group("name");
+            fullname = mat.group("fullname");
+        } else {
+            // bad import -- fake it
+            isStatic = compileSource.contains("static");
+            name = fullname = compileSource;
+        }
+        String fullkey = (isStatic ? "static-" : "") + fullname;
+        boolean isStar = name.equals("*");
+        String keyName = isStar
+                ? fullname
+                : name;
+        SubKind snippetKind = isStar
+                ? (isStatic ? STATIC_IMPORT_ON_DEMAND_SUBKIND : TYPE_IMPORT_ON_DEMAND_SUBKIND)
+                : (isStatic ? SINGLE_STATIC_IMPORT_SUBKIND : SINGLE_TYPE_IMPORT_SUBKIND);
+        Snippet snip = new ImportSnippet(state.keyMap.keyForImport(keyName, snippetKind),
+                userSource, guts, fullname, name, snippetKind, fullkey, isStatic, isStar);
+        return declare(snip);
+    }
+
+    private static class EvalPretty extends Pretty {
+
+        private final Writer out;
+
+        public EvalPretty(Writer writer, boolean bln) {
+            super(writer, bln);
+            this.out = writer;
+        }
+
+        /**
+         * Print string, DO NOT replacing all non-ascii character with unicode
+         * escapes.
+         */
+        @Override
+        public void print(Object o) throws IOException {
+            out.write(o.toString());
+        }
+
+        static String prettyExpr(JCTree tree, boolean bln) {
+            StringWriter out = new StringWriter();
+            try {
+                new EvalPretty(out, bln).printExpr(tree);
+            } catch (IOException e) {
+                throw new AssertionError(e);
+            }
+            return out.toString();
+        }
+    }
+
+    private List<SnippetEvent> processVariables(String userSource, List<? extends Tree> units, String compileSource, ParseTask pt) {
+        List<SnippetEvent> allEvents = new ArrayList<>();
+        TreeDissector dis = new TreeDissector(pt);
+        for (Tree unitTree : units) {
+            VariableTree vt = (VariableTree) unitTree;
+            String name = vt.getName().toString();
+            String typeName = EvalPretty.prettyExpr((JCTree) vt.getType(), false);
+            Tree baseType = vt.getType();
+            TreeDependencyScanner tds = new TreeDependencyScanner();
+            tds.scan(baseType); // Not dependent on initializer
+            StringBuilder sbBrackets = new StringBuilder();
+            while (baseType instanceof ArrayTypeTree) {
+                //TODO handle annotations too
+                baseType = ((ArrayTypeTree) baseType).getType();
+                sbBrackets.append("[]");
+            }
+            Range rtype = dis.treeToRange(baseType);
+            Range runit = dis.treeToRange(vt);
+            runit = new Range(runit.begin, runit.end - 1);
+            ExpressionTree it = vt.getInitializer();
+            Range rinit = null;
+            int nameMax = runit.end - 1;
+            SubKind subkind;
+            if (it != null) {
+                subkind = SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND;
+                rinit = dis.treeToRange(it);
+                nameMax = rinit.begin - 1;
+            } else {
+                subkind = SubKind.VAR_DECLARATION_SUBKIND;
+            }
+            int nameStart = compileSource.lastIndexOf(name, nameMax);
+            if (nameStart < 0) {
+                throw new AssertionError("Name '" + name + "' not found");
+            }
+            int nameEnd = nameStart + name.length();
+            Range rname = new Range(nameStart, nameEnd);
+            Wrap guts = Wrap.varWrap(compileSource, rtype, sbBrackets.toString(), rname, rinit);
+            Snippet snip = new VarSnippet(state.keyMap.keyForVariable(name), userSource, guts,
+                    name, subkind, typeName,
+                    tds.declareReferences());
+            DiagList modDiag = modifierDiagnostics(vt.getModifiers(), dis, true);
+            List<SnippetEvent> res1 = declare(snip, modDiag);
+            allEvents.addAll(res1);
+        }
+
+        return allEvents;
+    }
+
+    private List<SnippetEvent> processExpression(String userSource, String compileSource) {
+        String name = null;
+        ExpressionInfo ei = typeOfExpression(compileSource);
+        ExpressionTree assignVar;
+        Wrap guts;
+        Snippet snip;
+        if (ei != null && ei.isNonVoid) {
+            String typeName = ei.typeName;
+            SubKind subkind;
+            if (ei.tree instanceof IdentifierTree) {
+                IdentifierTree id = (IdentifierTree) ei.tree;
+                name = id.getName().toString();
+                subkind = SubKind.VAR_VALUE_SUBKIND;
+
+            } else if (ei.tree instanceof AssignmentTree
+                    && (assignVar = ((AssignmentTree) ei.tree).getVariable()) instanceof IdentifierTree) {
+                name = assignVar.toString();
+                subkind = SubKind.ASSIGNMENT_SUBKIND;
+            } else {
+                subkind = SubKind.OTHER_EXPRESSION_SUBKIND;
+            }
+            if (shouldGenTempVar(subkind)) {
+                if (state.tempVariableNameGenerator != null) {
+                    name = state.tempVariableNameGenerator.get();
+                }
+                while (name == null || state.keyMap.doesVariableNameExist(name)) {
+                    name = "$" + ++varNumber;
+                }
+                guts = Wrap.tempVarWrap(compileSource, typeName, name);
+                Collection<String> declareReferences = null; //TODO
+                snip = new VarSnippet(state.keyMap.keyForVariable(name), userSource, guts,
+                        name, SubKind.TEMP_VAR_EXPRESSION_SUBKIND, typeName, declareReferences);
+            } else {
+                guts = Wrap.methodReturnWrap(compileSource);
+                snip = new ExpressionSnippet(state.keyMap.keyForExpression(name, typeName), userSource, guts,
+                        name, subkind);
+            }
+        } else {
+            guts = Wrap.methodWrap(compileSource);
+            if (ei == null) {
+                // We got no type info, check for not a statement by trying
+                AnalyzeTask at = trialCompile(guts);
+                if (at.getDiagnostics().hasNotStatement()) {
+                    guts = Wrap.methodReturnWrap(compileSource);
+                    at = trialCompile(guts);
+                }
+                if (at.hasErrors()) {
+                    return compileFailResult(at, userSource);
+                }
+            }
+            snip = new StatementSnippet(state.keyMap.keyForStatement(), userSource, guts);
+        }
+        return declare(snip);
+    }
+
+    private List<SnippetEvent> processClass(String userSource, Tree unitTree, String compileSource, SubKind snippetKind, ParseTask pt) {
+        TreeDependencyScanner tds = new TreeDependencyScanner();
+        tds.scan(unitTree);
+
+        TreeDissector dis = new TreeDissector(pt);
+
+        ClassTree klassTree = (ClassTree) unitTree;
+        String name = klassTree.getSimpleName().toString();
+        Wrap guts = Wrap.classMemberWrap(compileSource);
+        Wrap corralled = null; //TODO
+        Snippet snip = new TypeDeclSnippet(state.keyMap.keyForClass(name), userSource, guts,
+                name, snippetKind,
+                corralled, tds.declareReferences(), tds.bodyReferences());
+        DiagList modDiag = modifierDiagnostics(klassTree.getModifiers(), dis, false);
+        return declare(snip, modDiag);
+    }
+
+    private List<SnippetEvent> processStatement(String userSource, String compileSource) {
+        Wrap guts = Wrap.methodWrap(compileSource);
+        // Check for unreachable by trying
+        AnalyzeTask at = trialCompile(guts);
+        if (at.hasErrors()) {
+            if (at.getDiagnostics().hasUnreachableError()) {
+                guts = Wrap.methodUnreachableSemiWrap(compileSource);
+                at = trialCompile(guts);
+                if (at.hasErrors()) {
+                    if (at.getDiagnostics().hasUnreachableError()) {
+                        // Without ending semicolon
+                        guts = Wrap.methodUnreachableWrap(compileSource);
+                        at = trialCompile(guts);
+                    }
+                    if (at.hasErrors()) {
+                        return compileFailResult(at, userSource);
+                    }
+                }
+            } else {
+                return compileFailResult(at, userSource);
+            }
+        }
+        Snippet snip = new StatementSnippet(state.keyMap.keyForStatement(), userSource, guts);
+        return declare(snip);
+    }
+
+    private OuterWrap wrapInClass(String className, Set<Key> except, String userSource, Wrap guts, Collection<Snippet> plus) {
+        String imports = state.maps.packageAndImportsExcept(except, plus);
+        return OuterWrap.wrapInClass(state.maps.packageName(), className, imports, userSource, guts);
+    }
+
+    OuterWrap wrapInClass(Snippet snip, Set<Key> except, Wrap guts, Collection<Snippet> plus) {
+        return wrapInClass(snip.className(), except, snip.source(), guts, plus);
+    }
+
+    private AnalyzeTask trialCompile(Wrap guts) {
+        OuterWrap outer = wrapInClass(REPL_DOESNOTMATTER_CLASS_NAME,
+                Collections.emptySet(), "", guts, null);
+        return state.taskFactory.new AnalyzeTask(outer);
+    }
+
+    private List<SnippetEvent> processMethod(String userSource, Tree unitTree, String compileSource, ParseTask pt) {
+        TreeDependencyScanner tds = new TreeDependencyScanner();
+        tds.scan(unitTree);
+
+        MethodTree mt = (MethodTree) unitTree;
+        TreeDissector dis = new TreeDissector(pt);
+        DiagList modDiag = modifierDiagnostics(mt.getModifiers(), dis, true);
+        if (modDiag.hasErrors()) {
+            return compileFailResult(modDiag, userSource);
+        }
+        String unitName = mt.getName().toString();
+        Wrap guts = Wrap.classMemberWrap(compileSource);
+
+        Range modRange = dis.treeToRange(mt.getModifiers());
+        Range tpRange = dis.treeListToRange(mt.getTypeParameters());
+        Range typeRange = dis.treeToRange(mt.getReturnType());
+        String name = mt.getName().toString();
+        Range paramRange = dis.treeListToRange(mt.getParameters());
+        Range throwsRange = dis.treeListToRange(mt.getThrows());
+
+        String parameterTypes
+                = mt.getParameters()
+                .stream()
+                .map(param -> dis.treeToRange(param.getType()).part(compileSource))
+                .collect(Collectors.joining(","));
+        String signature = "(" + parameterTypes + ")" + typeRange.part(compileSource);
+
+        MethodKey key = state.keyMap.keyForMethod(name, parameterTypes);
+        // rewrap with correct Key index
+        Wrap corralled = Wrap.corralledMethod(compileSource,
+                modRange, tpRange, typeRange, name, paramRange, throwsRange, key.index());
+        Snippet snip = new MethodSnippet(key, userSource, guts,
+                unitName, signature,
+                corralled, tds.declareReferences(), tds.bodyReferences());
+        return declare(snip, modDiag);
+    }
+
+    /**
+     * The snippet has failed, return with the rejected event
+     *
+     * @param xt the task from which to extract the failure diagnostics
+     * @param userSource the incoming bad user source
+     * @return a rejected snippet event
+     */
+    private List<SnippetEvent> compileFailResult(BaseTask xt, String userSource) {
+        return compileFailResult(xt.getDiagnostics(), userSource);
+    }
+
+    /**
+     * The snippet has failed, return with the rejected event
+     *
+     * @param diags the failure diagnostics
+     * @param userSource the incoming bad user source
+     * @return a rejected snippet event
+     */
+    private List<SnippetEvent> compileFailResult(DiagList diags, String userSource) {
+        ErroneousKey key = state.keyMap.keyForErroneous();
+        Snippet snip = new ErroneousSnippet(key, userSource, null, SubKind.UNKNOWN_SUBKIND);
+        snip.setFailed(diags);
+        state.maps.installSnippet(snip);
+        return Collections.singletonList(new SnippetEvent(
+                snip, Status.NONEXISTENT, Status.REJECTED,
+                false, null, null, null)
+        );
+    }
+
+    private ExpressionInfo typeOfExpression(String expression) {
+        Wrap guts = Wrap.methodReturnWrap(expression);
+        TaskFactory.AnalyzeTask at = trialCompile(guts);
+        if (!at.hasErrors() && at.cuTree() != null) {
+            return new TreeDissector(at)
+                    .typeOfReturnStatement(at.messages(), state.maps::fullClassNameAndPackageToClass);
+        }
+        return null;
+    }
+
+    /**
+     * Should a temp var wrap the expression. TODO make this user configurable.
+     *
+     * @param snippetKind
+     * @return
+     */
+    private boolean shouldGenTempVar(SubKind snippetKind) {
+        return snippetKind == SubKind.OTHER_EXPRESSION_SUBKIND;
+    }
+
+    List<SnippetEvent> drop(Snippet si) {
+        Unit c = new Unit(state, si);
+
+        Set<Unit> ins = c.dependents().collect(toSet());
+        Set<Unit> outs = compileAndLoad(ins);
+
+        return events(c, outs, null, null);
+    }
+
+    private List<SnippetEvent> declare(Snippet si) {
+        return declare(si, new DiagList());
+    }
+
+    private List<SnippetEvent> declare(Snippet si, DiagList generatedDiagnostics) {
+        Unit c = new Unit(state, si, null, generatedDiagnostics);
+
+        // Ignores duplicates
+        //TODO: remove, modify, or move to edit
+        if (c.isRedundant()) {
+            return Collections.emptyList();
+        }
+
+        Set<Unit> ins = new LinkedHashSet<>();
+        ins.add(c);
+        Set<Unit> outs = compileAndLoad(ins);
+
+        if (!si.status().isDefined
+                && si.diagnostics().isEmpty()
+                && si.unresolved().isEmpty()) {
+            // did not succeed, but no record of it, extract from others
+            si.setDiagnostics(outs.stream()
+                    .flatMap(u -> u.snippet().diagnostics().stream())
+                    .collect(Collectors.toCollection(DiagList::new)));
+        }
+
+        // If appropriate, execute the snippet
+        String value = null;
+        Exception exception = null;
+        if (si.isExecutable() && si.status().isDefined) {
+            try {
+                value = state.executionControl().commandInvoke(state.maps.classFullName(si));
+                value = si.subKind().hasValue()
+                        ? expunge(value)
+                        : "";
+            } catch (EvalException ex) {
+                exception = translateExecutionException(ex);
+            } catch (UnresolvedReferenceException ex) {
+                exception = ex;
+            }
+        }
+        return events(c, outs, value, exception);
+    }
+
+    private List<SnippetEvent> events(Unit c, Collection<Unit> outs, String value, Exception exception) {
+        List<SnippetEvent> events = new ArrayList<>();
+        events.add(c.event(value, exception));
+        events.addAll(outs.stream()
+                .filter(u -> u != c)
+                .map(u -> u.event(null, null))
+                .collect(Collectors.toList()));
+        events.addAll(outs.stream()
+                .flatMap(u -> u.secondaryEvents().stream())
+                .collect(Collectors.toList()));
+        //System.err.printf("Events: %s\n", events);
+        return events;
+    }
+
+    private Set<Unit> compileAndLoad(Set<Unit> ins) {
+        if (ins.isEmpty()) {
+            return ins;
+        }
+        Set<Unit> replaced = new LinkedHashSet<>();
+        while (true) {
+            state.debug(DBG_GEN, "compileAndLoad  %s\n", ins);
+
+            ins.stream().forEach(u -> u.initialize(ins));
+            AnalyzeTask at = state.taskFactory.new AnalyzeTask(ins);
+            ins.stream().forEach(u -> u.setDiagnostics(at));
+            // corral any Snippets that need it
+            if (ins.stream().filter(u -> u.corralIfNeeded(ins)).count() > 0) {
+                // if any were corralled, re-analyze everything
+                AnalyzeTask cat = state.taskFactory.new AnalyzeTask(ins);
+                ins.stream().forEach(u -> u.setCorralledDiagnostics(cat));
+            }
+            ins.stream().forEach(u -> u.setStatus());
+            // compile and load the legit snippets
+            boolean success;
+            while (true) {
+                List<Unit> legit = ins.stream()
+                        .filter(u -> u.isDefined())
+                        .collect(toList());
+                state.debug(DBG_GEN, "compileAndLoad ins = %s -- legit = %s\n",
+                        ins, legit);
+                if (legit.isEmpty()) {
+                    // no class files can be generated
+                    success = true;
+                } else {
+                    // re-wrap with legit imports
+                    legit.stream().forEach(u -> u.setWrap(ins, legit));
+
+                    // generate class files for those capable
+                    CompileTask ct = state.taskFactory.new CompileTask(legit);
+                    if (!ct.compile()) {
+                        // oy! compile failed because of recursive new unresolved
+                        if (legit.stream()
+                                .filter(u -> u.smashingErrorDiagnostics(ct))
+                                .count() > 0) {
+                            // try again, with the erroreous removed
+                            continue;
+                        } else {
+                            state.debug(DBG_GEN, "Should never happen error-less failure - %s\n",
+                                    legit);
+                        }
+                    }
+
+                    // load all new classes
+                    load(legit.stream()
+                            .flatMap(u -> u.classesToLoad(ct.classInfoList(u)))
+                            .collect(toList()));
+                    // attempt to redefine the remaining classes
+                    List<Unit> toReplace = legit.stream()
+                            .filter(u -> !u.doRedefines())
+                            .collect(toList());
+
+                    // prevent alternating redefine/replace cyclic dependency
+                    // loop by replacing all that have been replaced
+                    if (!toReplace.isEmpty()) {
+                        replaced.addAll(toReplace);
+                        replaced.stream().forEach(u -> u.markForReplacement());
+                    }
+
+                    success = toReplace.isEmpty();
+                }
+                break;
+            }
+
+            // add any new dependencies to the working set
+            List<Unit> newDependencies = ins.stream()
+                    .flatMap(u -> u.effectedDependents())
+                    .collect(toList());
+            state.debug(DBG_GEN, "compileAndLoad %s -- deps: %s  success: %s\n",
+                    ins, newDependencies, success);
+            if (!ins.addAll(newDependencies) && success) {
+                // all classes that could not be directly loaded (because they
+                // are new) have been redefined, and no new dependnencies were
+                // identified
+                ins.stream().forEach(u -> u.finish());
+                return ins;
+            }
+        }
+    }
+
+    private void load(List<ClassInfo> cil) {
+        if (!cil.isEmpty()) {
+            state.executionControl().commandLoad(cil);
+        }
+    }
+
+    private EvalException translateExecutionException(EvalException ex) {
+        StackTraceElement[] raw = ex.getStackTrace();
+        int last = raw.length;
+        do {
+            if (last == 0) {
+                last = raw.length - 1;
+                break;
+            }
+        } while (!isWrap(raw[--last]));
+        StackTraceElement[] elems = new StackTraceElement[last + 1];
+        for (int i = 0; i <= last; ++i) {
+            StackTraceElement r = raw[i];
+            String rawKlass = r.getClassName();
+            Matcher matcher = prefixPattern.matcher(rawKlass);
+            String num;
+            if (matcher.find() && (num = matcher.group("num")) != null) {
+                int end = matcher.end();
+                if (rawKlass.charAt(end - 1) == '$') {
+                    --end;
+                }
+                int id = Integer.parseInt(num);
+                Snippet si = state.maps.getSnippet(id);
+                String klass = expunge(rawKlass);
+                String method = r.getMethodName().equals(DOIT_METHOD_NAME) ? "" : r.getMethodName();
+                String file = "#" + id;
+                int line = si.outerWrap().wrapLineToSnippetLine(r.getLineNumber() - 1) + 1;
+                elems[i] = new StackTraceElement(klass, method, file, line);
+            } else if (r.getFileName().equals("<none>")) {
+                elems[i] = new StackTraceElement(r.getClassName(), r.getMethodName(), null, r.getLineNumber());
+            } else {
+                elems[i] = r;
+            }
+        }
+        String msg = ex.getMessage();
+        if (msg.equals("<none>")) {
+            msg = null;
+        }
+        return new EvalException(msg, ex.getExceptionClassName(), elems);
+    }
+
+    private boolean isWrap(StackTraceElement ste) {
+        return prefixPattern.matcher(ste.getClassName()).find();
+    }
+
+    private DiagList modifierDiagnostics(ModifiersTree modtree,
+            final TreeDissector dis, boolean isAbstractProhibited) {
+
+        class ModifierDiagnostic extends Diag {
+
+            final boolean fatal;
+            final String message;
+
+            ModifierDiagnostic(List<Modifier> list, boolean fatal) {
+                this.fatal = fatal;
+                StringBuilder sb = new StringBuilder();
+                sb.append((list.size() > 1) ? "Modifiers " : "Modifier ");
+                for (Modifier mod : list) {
+                    sb.append("'");
+                    sb.append(mod.toString());
+                    sb.append("' ");
+                }
+                sb.append("not permitted in top-level declarations");
+                if (!fatal) {
+                    sb.append(", ignored");
+                }
+                this.message = sb.toString();
+            }
+
+            @Override
+            public boolean isError() {
+                return fatal;
+            }
+
+            @Override
+            public long getPosition() {
+                return dis.getStartPosition(modtree);
+            }
+
+            @Override
+            public long getStartPosition() {
+                return dis.getStartPosition(modtree);
+            }
+
+            @Override
+            public long getEndPosition() {
+                return dis.getEndPosition(modtree);
+            }
+
+            @Override
+            public String getCode() {
+                return fatal
+                        ? "jdk.eval.error.illegal.modifiers"
+                        : "jdk.eval.warn.illegal.modifiers";
+            }
+
+            @Override
+            public String getMessage(Locale locale) {
+                return message;
+            }
+
+            @Override
+            Unit unitOrNull() {
+                return null;
+            }
+        }
+
+        List<Modifier> list = new ArrayList<>();
+        boolean fatal = false;
+        for (Modifier mod : modtree.getFlags()) {
+            switch (mod) {
+                case SYNCHRONIZED:
+                case NATIVE:
+                    list.add(mod);
+                    fatal = true;
+                    break;
+                case ABSTRACT:
+                    if (isAbstractProhibited) {
+                        list.add(mod);
+                        fatal = true;
+                    }
+                    break;
+                case PUBLIC:
+                case PROTECTED:
+                case PRIVATE:
+                case STATIC:
+                case FINAL:
+                    list.add(mod);
+                    break;
+            }
+        }
+        return list.isEmpty()
+                ? new DiagList()
+                : new DiagList(new ModifierDiagnostic(list, fatal));
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java
new file mode 100644
index 0000000..6c7a5f8
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+/**
+ * Wraps an exception thrown in the remotely executing client.
+ * An instance of <code>EvalException</code> can be returned in the
+ * {@link jdk.jshell.SnippetEvent#exception()} query.
+ * The name of the exception thrown is available from
+ * {@link jdk.jshell.EvalException#getExceptionClassName()}.
+ * Message and stack can be queried by methods on <code>Exception</code>.
+ * <p>
+ * Note that in stack trace frames representing JShell Snippets,
+ * <code>StackTraceElement.getFileName()</code> will return "#" followed by
+ * the Snippet id and for snippets without a method name (for example an
+ * expression) <code>StackTraceElement.getMethodName()</code> will be the
+ * empty string.
+ */
+@SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+public class EvalException extends Exception {
+    private final String exceptionClass;
+
+    EvalException(String message, String exceptionClass, StackTraceElement[] stackElements) {
+        super(message);
+        this.exceptionClass = exceptionClass;
+        this.setStackTrace(stackElements);
+    }
+
+    /**
+     * Returns the name of the Throwable subclass which was thrown in the
+     * executing client. Note this class may not be loaded in the controlling
+     * process.
+     * See
+     * {@link java.lang.Class#getName() Class.getName()} for the format of the string.
+     * @return the name of the exception class as a String
+     */
+    public String getExceptionClassName() {
+        return exceptionClass;
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java
new file mode 100644
index 0000000..3753ea8
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import static jdk.internal.jshell.remote.RemoteCodes.*;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import com.sun.jdi.*;
+import java.io.EOFException;
+import java.util.List;
+import java.util.Map;
+import jdk.jshell.ClassTracker.ClassInfo;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+
+/**
+ * Controls the remote execution environment.
+ *
+ * @author Robert Field
+ */
+class ExecutionControl {
+
+    private final JDIEnv env;
+    private final SnippetMaps maps;
+    private JDIEventHandler handler;
+    private Socket socket;
+    private ObjectInputStream in;
+    private ObjectOutputStream out;
+    private final JShell proc;
+
+    ExecutionControl(JDIEnv env, SnippetMaps maps, JShell proc) {
+        this.env = env;
+        this.maps = maps;
+        this.proc = proc;
+    }
+
+    void launch() throws IOException {
+        try (ServerSocket listener = new ServerSocket(0)) {
+            // timeout after 60 seconds
+            listener.setSoTimeout(60000);
+            int port = listener.getLocalPort();
+            jdiGo(port);
+            socket = listener.accept();
+            // out before in -- match remote creation so we don't hang
+            out = new ObjectOutputStream(socket.getOutputStream());
+            in = new ObjectInputStream(socket.getInputStream());
+        }
+    }
+
+    void commandExit() {
+        try {
+            if (out != null) {
+                out.writeInt(CMD_EXIT);
+                out.flush();
+            }
+            JDIConnection c = env.connection();
+            if (c != null) {
+                c.disposeVM();
+            }
+        } catch (IOException ex) {
+            proc.debug(DBG_GEN, "Exception on JDI exit: %s\n", ex);
+        }
+    }
+
+
+    boolean commandLoad(List<ClassInfo> cil) {
+        try {
+            out.writeInt(CMD_LOAD);
+            out.writeInt(cil.size());
+            for (ClassInfo ci : cil) {
+                out.writeUTF(ci.getClassName());
+                out.writeObject(ci.getBytes());
+            }
+            out.flush();
+            return readAndReportResult();
+        } catch (IOException ex) {
+            proc.debug(DBG_GEN, "IOException on remote load operation: %s\n", ex);
+            return false;
+        }
+    }
+
+    String commandInvoke(String classname) throws EvalException, UnresolvedReferenceException {
+        try {
+            synchronized (STOP_LOCK) {
+                userCodeRunning = true;
+            }
+            out.writeInt(CMD_INVOKE);
+            out.writeUTF(classname);
+            out.flush();
+            if (readAndReportExecutionResult()) {
+                String result = in.readUTF();
+                return result;
+            }
+        } catch (EOFException ex) {
+            env.shutdown();
+        } catch (IOException | ClassNotFoundException ex) {
+            proc.debug(DBG_GEN, "Exception on remote invoke: %s\n", ex);
+            return "Execution failure: " + ex.getMessage();
+        } finally {
+            synchronized (STOP_LOCK) {
+                userCodeRunning = false;
+            }
+        }
+        return "";
+    }
+
+    String commandVarValue(String classname, String varname) {
+        try {
+            out.writeInt(CMD_VARVALUE);
+            out.writeUTF(classname);
+            out.writeUTF(varname);
+            out.flush();
+            if (readAndReportResult()) {
+                String result = in.readUTF();
+                return result;
+            }
+        } catch (EOFException ex) {
+            env.shutdown();
+        } catch (IOException ex) {
+            proc.debug(DBG_GEN, "Exception on remote var value: %s\n", ex);
+            return "Execution failure: " + ex.getMessage();
+        }
+        return "";
+    }
+
+    boolean commandAddToClasspath(String cp) {
+        try {
+            out.writeInt(CMD_CLASSPATH);
+            out.writeUTF(cp);
+            out.flush();
+            return readAndReportResult();
+        } catch (IOException ex) {
+            throw new InternalError("Classpath addition failed: " + cp, ex);
+        }
+    }
+
+    boolean commandRedefine(Map<ReferenceType, byte[]> mp) {
+        try {
+            env.vm().redefineClasses(mp);
+            return true;
+        } catch (UnsupportedOperationException ex) {
+            return false;
+        } catch (Exception ex) {
+            proc.debug(DBG_GEN, "Exception on JDI redefine: %s\n", ex);
+            return false;
+        }
+    }
+
+    ReferenceType nameToRef(String name) {
+        List<ReferenceType> rtl = env.vm().classesByName(name);
+        if (rtl.size() != 1) {
+            return null;
+        }
+        return rtl.get(0);
+    }
+
+    private boolean readAndReportResult() throws IOException {
+        int ok = in.readInt();
+        switch (ok) {
+            case RESULT_SUCCESS:
+                return true;
+            case RESULT_FAIL: {
+                String ex = in.readUTF();
+                proc.debug(DBG_GEN, "Exception on remote operation: %s\n", ex);
+                return false;
+            }
+            default: {
+                proc.debug(DBG_GEN, "Bad remote result code: %s\n", ok);
+                return false;
+            }
+        }
+    }
+
+    private boolean readAndReportExecutionResult() throws IOException, ClassNotFoundException, EvalException, UnresolvedReferenceException {
+        int ok = in.readInt();
+        switch (ok) {
+            case RESULT_SUCCESS:
+                return true;
+            case RESULT_FAIL: {
+                String ex = in.readUTF();
+                proc.debug(DBG_GEN, "Exception on remote operation: %s\n", ex);
+                return false;
+            }
+            case RESULT_EXCEPTION: {
+                String exceptionClassName = in.readUTF();
+                String message = in.readUTF();
+                StackTraceElement[] elems = readStackTrace();
+                EvalException ee = new EvalException(message, exceptionClassName, elems);
+                throw ee;
+            }
+            case RESULT_CORRALLED: {
+                int id = in.readInt();
+                StackTraceElement[] elems = readStackTrace();
+                Snippet si = maps.getSnippet(id);
+                throw new UnresolvedReferenceException((MethodSnippet) si, elems);
+            }
+            case RESULT_KILLED: {
+                proc.out.println("Killed.");
+                return false;
+            }
+            default: {
+                proc.debug(DBG_GEN, "Bad remote result code: %s\n", ok);
+                return false;
+            }
+        }
+    }
+
+    private StackTraceElement[] readStackTrace() throws IOException {
+        int elemCount = in.readInt();
+        StackTraceElement[] elems = new StackTraceElement[elemCount];
+        for (int i = 0; i < elemCount; ++i) {
+            String className = in.readUTF();
+            String methodName = in.readUTF();
+            String fileName = in.readUTF();
+            int line = in.readInt();
+            elems[i] = new StackTraceElement(className, methodName, fileName, line);
+        }
+        return elems;
+    }
+
+    private void jdiGo(int port) {
+        //MessageOutput.textResources = ResourceBundle.getBundle("impl.TTYResources",
+        //        Locale.getDefault());
+
+        String connect = "com.sun.jdi.CommandLineLaunch:";
+        String cmdLine = "jdk.internal.jshell.remote.RemoteAgent";
+        String classPath = System.getProperty("java.class.path");
+        String bootclassPath = System.getProperty("sun.boot.class.path");
+        String javaArgs = "-classpath " + classPath + " -Xbootclasspath:" + bootclassPath;
+
+        String connectSpec = connect + "main=" + cmdLine + " " + port + ",options=" + javaArgs + ",";
+        boolean launchImmediately = true;
+        int traceFlags = 0;// VirtualMachine.TRACE_SENDS | VirtualMachine.TRACE_EVENTS;
+
+        env.init(connectSpec, launchImmediately, traceFlags);
+
+        if (env.connection().isOpen() && env.vm().canBeModified()) {
+            /*
+             * Connection opened on startup. Start event handler
+             * immediately, telling it (through arg 2) to stop on the
+             * VM start event.
+             */
+            handler = new JDIEventHandler(env);
+        }
+    }
+
+    private final Object STOP_LOCK = new Object();
+    private boolean userCodeRunning = false;
+
+    void commandStop() {
+        synchronized (STOP_LOCK) {
+            if (!userCodeRunning)
+                return ;
+
+            VirtualMachine vm = handler.env.vm();
+            vm.suspend();
+            try {
+                OUTER: for (ThreadReference thread : vm.allThreads()) {
+                    // could also tag the thread (e.g. using name), to find it easier
+                    for (StackFrame frame : thread.frames()) {
+                        String remoteAgentName = "jdk.internal.jshell.remote.RemoteAgent";
+                        if (remoteAgentName.equals(frame.location().declaringType().name()) &&
+                            "commandLoop".equals(frame.location().method().name())) {
+                            ObjectReference thiz = frame.thisObject();
+                            if (((BooleanValue) thiz.getValue(thiz.referenceType().fieldByName("inClientCode"))).value()) {
+                                thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(true));
+                                ObjectReference stopInstance = (ObjectReference) thiz.getValue(thiz.referenceType().fieldByName("stopException"));
+
+                                vm.resume();
+                                proc.debug(DBG_GEN, "Attempting to stop the client code...\n");
+                                thread.stop(stopInstance);
+                                thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(false));
+                            }
+
+                            break OUTER;
+                        }
+                    }
+                }
+            } catch (ClassNotLoadedException | IncompatibleThreadStateException | InvalidTypeException  ex) {
+                proc.debug(DBG_GEN, "Exception on remote stop: %s\n", ex);
+            } finally {
+                vm.resume();
+            }
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java
new file mode 100644
index 0000000..6934bee
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import jdk.jshell.Key.ExpressionKey;
+
+/**
+ * Snippet for an assignment or variable-value expression.
+ * The Kind is {@link jdk.jshell.Snippet.Kind#EXPRESSION}.
+ * <p>
+ * <code>ExpressionSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ * @jls 15: Expression.
+ */
+public class ExpressionSnippet extends Snippet {
+
+    ExpressionSnippet(ExpressionKey key, String userSource, Wrap guts, String name, SubKind subkind) {
+        super(key, userSource, guts, name, subkind);
+    }
+
+    /**
+     * Variable name which is the value of the expression. Since the expression
+     * is either just a variable identifier or it is an assignment
+     * to a variable, there is always a variable which is the subject of the
+     * expression. All other forms of expression become temporary variables
+     * which are instead referenced by a {@link VarSnippet}.
+     * @return the name of the variable which is the subject of the expression.
+     */
+    @Override
+    public String name() {
+        return key().name();
+    }
+
+    /**
+     * Type of the expression
+     * @return String representation of the type of the expression.
+     */
+    public String typeName() {
+        return key().typeName();
+    }
+
+    /**** internal access ****/
+
+    @Override
+    ExpressionKey key() {
+        return (ExpressionKey) super.key();
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/GeneralWrap.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/GeneralWrap.java
new file mode 100644
index 0000000..217fcd7
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/GeneralWrap.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+/**
+ * Common interface for all wrappings of snippet source to Java source.
+ *
+ * @author Robert Field
+ */
+interface GeneralWrap {
+
+    String wrapped();
+
+    int snippetIndexToWrapIndex(int sni);
+
+    int wrapIndexToSnippetIndex(int wi);
+
+    default int wrapIndexToSnippetIndex(long wi) {
+        return wrapIndexToSnippetIndex((int) wi);
+    }
+
+    int firstSnippetIndex();
+
+    int lastSnippetIndex();
+
+    int snippetLineToWrapLine(int snline);
+
+    int wrapLineToSnippetLine(int wline);
+
+    int firstSnippetLine();
+
+    int lastSnippetLine();
+
+    default String debugPos(long lpos) {
+        int pos = (int) lpos;
+        int len = wrapped().length();
+        return wrapped().substring(Math.max(0, pos - 10), Math.max(0, Math.min(len, pos)))
+                + "###"
+                + wrapped().substring(Math.max(0, Math.min(len, pos)), Math.max(0, Math.min(len, pos + 10)));
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java
new file mode 100644
index 0000000..c3620de
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import jdk.jshell.Key.ImportKey;
+
+/**
+ * Snippet for an import declaration.
+ * The Kind is {@link jdk.jshell.Snippet.Kind#IMPORT}.
+ * <p>
+ * <code>ImportSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ * @jls 8.3: importDeclaration.
+ */
+public class ImportSnippet extends PersistentSnippet {
+
+    final String fullname;
+    final String fullkey;
+    final boolean isStatic;
+    final boolean isStar;
+
+    ImportSnippet(ImportKey key, String userSource, Wrap guts,
+            String fullname, String name, SubKind subkind, String fullkey,
+            boolean isStatic, boolean isStar) {
+        super(key, userSource, guts, name, subkind);
+        this.fullname = fullname;
+        this.fullkey = fullkey;
+        this.isStatic = isStatic;
+        this.isStar = isStar;
+    }
+
+    /**
+     * The identifying name of the import. For on-demand imports
+     * ({@link jdk.jshell.Snippet.SubKind#TYPE_IMPORT_ON_DEMAND_SUBKIND} or
+     * ({@link jdk.jshell.Snippet.SubKind#STATIC_IMPORT_ON_DEMAND_SUBKIND})
+     * that is the full specifier including any
+     * qualifiers and the asterisks. For single imports
+     * ({@link jdk.jshell.Snippet.SubKind#SINGLE_TYPE_IMPORT_SUBKIND} or
+     * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}),
+     * it is the imported name. That is, the unqualified name.
+     * @return the name of the import.
+     */
+    @Override
+    public String name() {
+        return key().name();
+    }
+
+    /**** internal access ****/
+
+    @Override
+    ImportKey key() {
+        return (ImportKey) super.key();
+    }
+
+    boolean isStatic() {
+        return isStatic;
+    }
+
+    @Override
+    String importLine(JShell state) {
+        return source();
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIConnection.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIConnection.java
new file mode 100644
index 0000000..663eb20
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIConnection.java
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+/*
+ * This source code is provided to illustrate the usage of a given feature
+ * or technique and has been deliberately simplified. Additional steps
+ * required for a production-quality application, such as security checks,
+ * input validation and proper error handling, might not be present in
+ * this sample code.
+ */
+
+
+package jdk.jshell;
+
+import com.sun.jdi.*;
+import com.sun.jdi.connect.*;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+
+/**
+ * Connection to a Java Debug Interface VirtualMachine instance.
+ * Adapted from jdb VMConnection. Message handling, exception handling, and I/O
+ * redirection changed.  Interface to JShell added.
+ */
+class JDIConnection {
+
+    private VirtualMachine vm;
+    private Process process = null;
+    private int outputCompleteCount = 0;
+
+    private final JShell proc;
+    private final JDIEnv env;
+    private final Connector connector;
+    private final Map<String, com.sun.jdi.connect.Connector.Argument> connectorArgs;
+    private final int traceFlags;
+
+    synchronized void notifyOutputComplete() {
+        outputCompleteCount++;
+        notifyAll();
+    }
+
+    synchronized void waitOutputComplete() {
+        // Wait for stderr and stdout
+        if (process != null) {
+            while (outputCompleteCount < 2) {
+                try {wait();} catch (InterruptedException e) {}
+            }
+        }
+    }
+
+    private Connector findConnector(String name) {
+        for (Connector cntor :
+                 Bootstrap.virtualMachineManager().allConnectors()) {
+            if (cntor.name().equals(name)) {
+                return cntor;
+            }
+        }
+        return null;
+    }
+
+    private Map <String, com.sun.jdi.connect.Connector.Argument> parseConnectorArgs(Connector connector, String argString) {
+        Map<String, com.sun.jdi.connect.Connector.Argument> arguments = connector.defaultArguments();
+
+        /*
+         * We are parsing strings of the form:
+         *    name1=value1,[name2=value2,...]
+         * However, the value1...valuen substrings may contain
+         * embedded comma(s), so make provision for quoting inside
+         * the value substrings. (Bug ID 4285874)
+         */
+        String regexPattern =
+            "(quote=[^,]+,)|" +           // special case for quote=.,
+            "(\\w+=)" +                   // name=
+            "(((\"[^\"]*\")|" +           //   ( "l , ue"
+            "('[^']*')|" +                //     'l , ue'
+            "([^,'\"]+))+,)";             //     v a l u e )+ ,
+        Pattern p = Pattern.compile(regexPattern);
+        Matcher m = p.matcher(argString);
+        while (m.find()) {
+            int startPosition = m.start();
+            int endPosition = m.end();
+            if (startPosition > 0) {
+                /*
+                 * It is an error if parsing skips over any part of argString.
+                 */
+                throw new IllegalArgumentException("Illegal connector argument" +
+                                          argString);
+            }
+
+            String token = argString.substring(startPosition, endPosition);
+            int index = token.indexOf('=');
+            String name = token.substring(0, index);
+            String value = token.substring(index + 1,
+                                           token.length() - 1); // Remove comma delimiter
+
+            /*
+             * for values enclosed in quotes (single and/or double quotes)
+             * strip off enclosing quote chars
+             * needed for quote enclosed delimited substrings
+             */
+            if (name.equals("options")) {
+                StringBuilder sb = new StringBuilder();
+                for (String s : splitStringAtNonEnclosedWhiteSpace(value)) {
+                    while (isEnclosed(s, "\"") || isEnclosed(s, "'")) {
+                        s = s.substring(1, s.length() - 1);
+                    }
+                    sb.append(s);
+                    sb.append(" ");
+                }
+                value = sb.toString();
+            }
+
+            Connector.Argument argument = arguments.get(name);
+            if (argument == null) {
+                throw new IllegalArgumentException("Argument is not defined for connector:" +
+                                          name + " -- " + connector.name());
+            }
+            argument.setValue(value);
+
+            argString = argString.substring(endPosition); // Remove what was just parsed...
+            m = p.matcher(argString);                     //    and parse again on what is left.
+        }
+        if ((! argString.equals(",")) && (argString.length() > 0)) {
+            /*
+             * It is an error if any part of argString is left over,
+             * unless it was empty to begin with.
+             */
+            throw new IllegalArgumentException("Illegal connector argument" + argString);
+        }
+        return arguments;
+    }
+
+    private static boolean isEnclosed(String value, String enclosingChar) {
+        if (value.indexOf(enclosingChar) == 0) {
+            int lastIndex = value.lastIndexOf(enclosingChar);
+            if (lastIndex > 0 && lastIndex  == value.length() - 1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static List<String> splitStringAtNonEnclosedWhiteSpace(String value) throws IllegalArgumentException {
+        List<String> al = new ArrayList<>();
+        char[] arr;
+        int startPosition = 0;
+        int endPosition;
+        final char SPACE = ' ';
+        final char DOUBLEQ = '"';
+        final char SINGLEQ = '\'';
+
+        /*
+         * An "open" or "active" enclosing state is where
+         * the first valid start quote qualifier is found,
+         * and there is a search in progress for the
+         * relevant end matching quote
+         *
+         * enclosingTargetChar set to SPACE
+         * is used to signal a non open enclosing state
+         */
+        char enclosingTargetChar = SPACE;
+
+        if (value == null) {
+            throw new IllegalArgumentException("value string is null");
+        }
+
+        // split parameter string into individual chars
+        arr = value.toCharArray();
+
+        for (int i = 0; i < arr.length; i++) {
+            switch (arr[i]) {
+                case SPACE: {
+                    // do nothing for spaces
+                    // unless last in array
+                    if (isLastChar(arr, i)) {
+                        endPosition = i;
+                        // break for substring creation
+                        break;
+                    }
+                    continue;
+                }
+                case DOUBLEQ:
+                case SINGLEQ: {
+                    if (enclosingTargetChar == arr[i]) {
+                        // potential match to close open enclosing
+                        if (isNextCharWhitespace(arr, i)) {
+                            // if peek next is whitespace
+                            // then enclosing is a valid substring
+                            endPosition = i;
+                            // reset enclosing target char
+                            enclosingTargetChar = SPACE;
+                            // break for substring creation
+                            break;
+                        }
+                    }
+                    if (enclosingTargetChar == SPACE) {
+                        // no open enclosing state
+                        // handle as normal char
+                        if (isPreviousCharWhitespace(arr, i)) {
+                            startPosition = i;
+                            // peek forward for end candidates
+                            if (value.indexOf(arr[i], i + 1) >= 0) {
+                                // set open enclosing state by
+                                // setting up the target char
+                                enclosingTargetChar = arr[i];
+                            } else {
+                                // no more target chars left to match
+                                // end enclosing, handle as normal char
+                                if (isNextCharWhitespace(arr, i)) {
+                                    endPosition = i;
+                                    // break for substring creation
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    continue;
+                }
+                default: {
+                    // normal non-space, non-" and non-' chars
+                    if (enclosingTargetChar == SPACE) {
+                        // no open enclosing state
+                        if (isPreviousCharWhitespace(arr, i)) {
+                            // start of space delim substring
+                            startPosition = i;
+                        }
+                        if (isNextCharWhitespace(arr, i)) {
+                            // end of space delim substring
+                            endPosition = i;
+                            // break for substring creation
+                            break;
+                        }
+                    }
+                    continue;
+                }
+            }
+
+            // break's end up here
+            if (startPosition > endPosition) {
+                throw new IllegalArgumentException("Illegal option values");
+            }
+
+            // extract substring and add to List<String>
+            al.add(value.substring(startPosition, ++endPosition));
+
+            // set new start position
+            i = startPosition = endPosition;
+
+        } // for loop
+
+        return al;
+    }
+
+    static private boolean isPreviousCharWhitespace(char[] arr, int curr_pos) {
+        return isCharWhitespace(arr, curr_pos - 1);
+    }
+
+    static private boolean isNextCharWhitespace(char[] arr, int curr_pos) {
+        return isCharWhitespace(arr, curr_pos + 1);
+    }
+
+    static private boolean isCharWhitespace(char[] arr, int pos) {
+        if (pos < 0 || pos >= arr.length) {
+            // outside arraybounds is considered an implicit space
+            return true;
+        }
+        return (arr[pos] == ' ');
+    }
+
+    static private boolean isLastChar(char[] arr, int pos) {
+        return (pos + 1 == arr.length);
+    }
+
+    JDIConnection(JDIEnv env, String connectSpec, int traceFlags, JShell proc) {
+        this.env = env;
+        this.proc = proc;
+        String nameString;
+        String argString;
+        int index = connectSpec.indexOf(':');
+        if (index == -1) {
+            nameString = connectSpec;
+            argString = "";
+        } else {
+            nameString = connectSpec.substring(0, index);
+            argString = connectSpec.substring(index + 1);
+        }
+
+        connector = findConnector(nameString);
+        if (connector == null) {
+            throw new IllegalArgumentException("No connector named: " + nameString);
+        }
+
+        connectorArgs = parseConnectorArgs(connector, argString);
+        this.traceFlags = traceFlags;
+    }
+
+    synchronized VirtualMachine open() {
+        if (connector instanceof LaunchingConnector) {
+            vm = launchTarget();
+        } else if (connector instanceof AttachingConnector) {
+            vm = attachTarget();
+        } else if (connector instanceof ListeningConnector) {
+            vm = listenTarget();
+        } else {
+            throw new InternalError("Invalid connect type");
+        }
+        vm.setDebugTraceMode(traceFlags);
+        // Uncomment here and below to enable event requests
+        // installEventRequests(vm);
+
+        return vm;
+    }
+
+    boolean setConnectorArg(String name, String value) {
+        /*
+         * Too late if the connection already made
+         */
+        if (vm != null) {
+            return false;
+        }
+
+        Connector.Argument argument = connectorArgs.get(name);
+        if (argument == null) {
+            return false;
+        }
+        argument.setValue(value);
+        return true;
+    }
+
+    String connectorArg(String name) {
+        Connector.Argument argument = connectorArgs.get(name);
+        if (argument == null) {
+            return "";
+        }
+        return argument.value();
+    }
+
+    public synchronized VirtualMachine vm() {
+        if (vm == null) {
+            throw new JDINotConnectedException();
+        } else {
+            return vm;
+        }
+    }
+
+    boolean isOpen() {
+        return (vm != null);
+    }
+
+    boolean isLaunch() {
+        return (connector instanceof LaunchingConnector);
+    }
+
+    public void disposeVM() {
+        try {
+            if (vm != null) {
+                vm.dispose(); // This could NPE, so it is caught below
+                vm = null;
+            }
+        } catch (VMDisconnectedException | NullPointerException ex) {
+            // Ignore if already closed
+        } finally {
+            if (process != null) {
+                process.destroy();
+                process = null;
+            }
+            waitOutputComplete();
+        }
+    }
+
+/*** Preserved for possible future support of event requests
+
+    private void installEventRequests(VirtualMachine vm) {
+        if (vm.canBeModified()){
+            setEventRequests(vm);
+            resolveEventRequests();
+        }
+    }
+
+    private void setEventRequests(VirtualMachine vm) {
+        EventRequestManager erm = vm.eventRequestManager();
+
+        // Normally, we want all uncaught exceptions.  We request them
+        // via the same mechanism as Commands.commandCatchException()
+        // so the user can ignore them later if they are not
+        // interested.
+        // FIXME: this works but generates spurious messages on stdout
+        //        during startup:
+        //          Set uncaught java.lang.Throwable
+        //          Set deferred uncaught java.lang.Throwable
+        Commands evaluator = new Commands();
+        evaluator.commandCatchException
+            (new StringTokenizer("uncaught java.lang.Throwable"));
+
+        ThreadStartRequest tsr = erm.createThreadStartRequest();
+        tsr.enable();
+        ThreadDeathRequest tdr = erm.createThreadDeathRequest();
+        tdr.enable();
+    }
+
+    private void resolveEventRequests() {
+        Env.specList.resolveAll();
+    }
+***/
+
+    private void dumpStream(InputStream inStream, final PrintStream pStream) throws IOException {
+        BufferedReader in =
+            new BufferedReader(new InputStreamReader(inStream));
+        int i;
+        try {
+            while ((i = in.read()) != -1) {
+                pStream.print((char) i);
+            }
+        } catch (IOException ex) {
+            String s = ex.getMessage();
+            if (!s.startsWith("Bad file number")) {
+                throw ex;
+            }
+            // else we got a Bad file number IOException which just means
+            // that the debuggee has gone away.  We'll just treat it the
+            // same as if we got an EOF.
+        }
+    }
+
+    /**
+     *  Create a Thread that will retrieve and display any output.
+     *  Needs to be high priority, else debugger may exit before
+     *  it can be displayed.
+     */
+    private void displayRemoteOutput(final InputStream inStream, final PrintStream pStream) {
+        Thread thr = new Thread("output reader") {
+            @Override
+            public void run() {
+                try {
+                    dumpStream(inStream, pStream);
+                } catch (IOException ex) {
+                    proc.debug(ex, "Failed reading output");
+                    env.shutdown();
+                } finally {
+                    notifyOutputComplete();
+                }
+            }
+        };
+        thr.setPriority(Thread.MAX_PRIORITY-1);
+        thr.start();
+    }
+
+    /**
+     *  Create a Thread that will ship all input to remote.
+     *  Does it need be high priority?
+     */
+    private void readRemoteInput(final OutputStream outStream, final InputStream inputStream) {
+        Thread thr = new Thread("input reader") {
+            @Override
+            public void run() {
+                try {
+                    byte[] buf = new byte[256];
+                    int cnt;
+                    while ((cnt = inputStream.read(buf)) != -1) {
+                        outStream.write(buf, 0, cnt);
+                        outStream.flush();
+                    }
+                } catch (IOException ex) {
+                    proc.debug(ex, "Failed reading output");
+                    env.shutdown();
+                }
+            }
+        };
+        thr.setPriority(Thread.MAX_PRIORITY-1);
+        thr.start();
+    }
+
+    /* launch child target vm */
+    private VirtualMachine launchTarget() {
+        LaunchingConnector launcher = (LaunchingConnector)connector;
+        try {
+            VirtualMachine new_vm = launcher.launch(connectorArgs);
+            process = new_vm.process();
+            displayRemoteOutput(process.getErrorStream(), proc.err);
+            displayRemoteOutput(process.getInputStream(), proc.out);
+            readRemoteInput(process.getOutputStream(), proc.in);
+            return new_vm;
+        } catch (Exception ex) {
+            reportLaunchFail(ex, "launch");
+        }
+        return null;
+    }
+
+    /* JShell currently uses only launch, preserved for futures: */
+    /* attach to running target vm */
+    private VirtualMachine attachTarget() {
+        AttachingConnector attacher = (AttachingConnector)connector;
+        try {
+            return attacher.attach(connectorArgs);
+        } catch (Exception ex) {
+            reportLaunchFail(ex, "attach");
+        }
+        return null;
+    }
+
+    /* JShell currently uses only launch, preserved for futures: */
+    /* listen for connection from target vm */
+    private VirtualMachine listenTarget() {
+        ListeningConnector listener = (ListeningConnector)connector;
+        try {
+            String retAddress = listener.startListening(connectorArgs);
+            proc.debug(DBG_GEN, "Listening at address: " + retAddress);
+            vm = listener.accept(connectorArgs);
+            listener.stopListening(connectorArgs);
+            return vm;
+        } catch (Exception ex) {
+            reportLaunchFail(ex, "listen");
+        }
+        return null;
+    }
+
+    private void reportLaunchFail(Exception ex, String context) {
+        throw new InternalError("Failed remote " + context + ": " + connector +
+                " -- " + connectorArgs, ex);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIEnv.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIEnv.java
new file mode 100644
index 0000000..6ec78d7
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIEnv.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import com.sun.jdi.*;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+
+/**
+ * Representation of a Java Debug Interface environment
+ * Select methods extracted from jdb Env; shutdown() adapted to JShell shutdown.
+ */
+class JDIEnv {
+
+    private JDIConnection connection;
+    private final JShell state;
+
+    JDIEnv(JShell state) {
+        this.state = state;
+    }
+
+    void init(String connectSpec, boolean openNow, int flags) {
+        connection = new JDIConnection(this, connectSpec, flags, state);
+        if (!connection.isLaunch() || openNow) {
+            connection.open();
+        }
+    }
+
+    JDIConnection connection() {
+        return connection;
+    }
+
+    VirtualMachine vm() {
+        return connection.vm();
+    }
+
+    void shutdown() {
+        if (connection != null) {
+            try {
+                connection.disposeVM();
+            } catch (VMDisconnectedException e) {
+                // Shutting down after the VM has gone away. This is
+                // not an error, and we just ignore it.
+            } catch (Throwable e) {
+                state.debug(DBG_GEN, null, "disposeVM threw: " + e);
+            }
+        }
+        if (state != null) { // If state has been set-up
+            try {
+                state.closeDown();
+            } catch (Throwable e) {
+                state.debug(DBG_GEN, null, "state().closeDown() threw: " + e);
+            }
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIEventHandler.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIEventHandler.java
new file mode 100644
index 0000000..adbf428
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIEventHandler.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1998, 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+
+/**
+ * Handler of Java Debug Interface events.
+ * Adapted from jdb EventHandler; Handling of events not used by JShell stubbed out.
+ */
+class JDIEventHandler implements Runnable {
+
+    Thread thread;
+    volatile boolean connected = true;
+    boolean completed = false;
+    String shutdownMessageKey;
+    final JDIEnv env;
+
+    JDIEventHandler(JDIEnv env) {
+        this.env = env;
+        this.thread = new Thread(this, "event-handler");
+        this.thread.start();
+    }
+
+    synchronized void shutdown() {
+        connected = false;  // force run() loop termination
+        thread.interrupt();
+        while (!completed) {
+            try {wait();} catch (InterruptedException exc) {}
+        }
+    }
+
+    @Override
+    public void run() {
+        EventQueue queue = env.vm().eventQueue();
+        while (connected) {
+            try {
+                EventSet eventSet = queue.remove();
+                boolean resumeStoppedApp = false;
+                EventIterator it = eventSet.eventIterator();
+                while (it.hasNext()) {
+                    resumeStoppedApp |= handleEvent(it.nextEvent());
+                }
+
+                if (resumeStoppedApp) {
+                    eventSet.resume();
+                }
+            } catch (InterruptedException exc) {
+                // Do nothing. Any changes will be seen at top of loop.
+            } catch (VMDisconnectedException discExc) {
+                handleDisconnectedException();
+                break;
+            }
+        }
+        synchronized (this) {
+            completed = true;
+            notifyAll();
+        }
+    }
+
+    private boolean handleEvent(Event event) {
+        if (event instanceof ExceptionEvent) {
+            exceptionEvent(event);
+        } else if (event instanceof WatchpointEvent) {
+            fieldWatchEvent(event);
+        } else if (event instanceof MethodEntryEvent) {
+            methodEntryEvent(event);
+        } else if (event instanceof MethodExitEvent) {
+            methodExitEvent(event);
+        } else if (event instanceof ClassPrepareEvent) {
+            classPrepareEvent(event);
+        } else if (event instanceof ThreadStartEvent) {
+            threadStartEvent(event);
+        } else if (event instanceof ThreadDeathEvent) {
+            threadDeathEvent(event);
+        } else if (event instanceof VMStartEvent) {
+            vmStartEvent(event);
+            return true;
+        } else {
+            handleExitEvent(event);
+        }
+        return true;
+    }
+
+    private boolean vmDied = false;
+
+    private void handleExitEvent(Event event) {
+        if (event instanceof VMDeathEvent) {
+            vmDied = true;
+            shutdownMessageKey = "The application exited";
+        } else if (event instanceof VMDisconnectEvent) {
+            connected = false;
+            if (!vmDied) {
+                shutdownMessageKey = "The application has been disconnected";
+            }
+        } else {
+            throw new InternalError("Unexpected event type: " +
+                    event.getClass());
+        }
+        env.shutdown();
+    }
+
+    synchronized void handleDisconnectedException() {
+        /*
+         * A VMDisconnectedException has happened while dealing with
+         * another event. We need to flush the event queue, dealing only
+         * with exit events (VMDeath, VMDisconnect) so that we terminate
+         * correctly.
+         */
+        EventQueue queue = env.vm().eventQueue();
+        while (connected) {
+            try {
+                EventSet eventSet = queue.remove();
+                EventIterator iter = eventSet.eventIterator();
+                while (iter.hasNext()) {
+                    handleExitEvent(iter.next());
+                }
+            } catch (InterruptedException exc) {
+                // ignore
+            } catch (InternalError exc) {
+                // ignore
+            }
+        }
+    }
+
+    private void vmStartEvent(Event event)  {
+        VMStartEvent se = (VMStartEvent)event;
+    }
+
+    private void methodEntryEvent(Event event)  {
+        MethodEntryEvent me = (MethodEntryEvent)event;
+    }
+
+    private void methodExitEvent(Event event)  {
+        MethodExitEvent me = (MethodExitEvent)event;
+    }
+
+    private void fieldWatchEvent(Event event)  {
+        WatchpointEvent fwe = (WatchpointEvent)event;
+    }
+
+    private void classPrepareEvent(Event event)  {
+        ClassPrepareEvent cle = (ClassPrepareEvent)event;
+    }
+
+    private void exceptionEvent(Event event) {
+        ExceptionEvent ee = (ExceptionEvent)event;
+    }
+
+    private void threadDeathEvent(Event event) {
+        ThreadDeathEvent tee = (ThreadDeathEvent)event;
+    }
+
+    private void threadStartEvent(Event event) {
+        ThreadStartEvent tse = (ThreadStartEvent)event;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDINotConnectedException.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDINotConnectedException.java
new file mode 100644
index 0000000..2b9407c
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDINotConnectedException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+/**
+ * Internal exception when Java Debug Interface VirtualMacine is not connected.
+ * Copy of jdb VMNotConnectedException.
+ */
+class JDINotConnectedException extends RuntimeException {
+
+    private static final long serialVersionUID = -7433430494903950165L;
+
+    public JDINotConnectedException() {
+        super();
+    }
+
+    public JDINotConnectedException(String s) {
+        super(s);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
new file mode 100644
index 0000000..7616da7
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+
+import java.util.function.Supplier;
+import jdk.internal.jshell.debug.InternalDebugControl;
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.toList;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_EVNT;
+import static jdk.jshell.Util.expunge;
+import jdk.jshell.Snippet.Status;
+
+/**
+ * The JShell evaluation state engine.  This is the central class in the JShell
+ * API.  A <code>JShell</code> instance holds the evolving compilation and
+ * execution state.  The state is changed with the instance methods
+ * {@link jdk.jshell.JShell#eval(java.lang.String) eval(String)},
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop(PersistentSnippet)} and
+ * {@link jdk.jshell.JShell#addToClasspath(java.lang.String) addToClasspath(String)}.
+ * The majority of methods query the state.
+ * A <code>JShell</code> instance also allows registering for events with
+ * {@link jdk.jshell.JShell#onSnippetEvent(java.util.function.Consumer) onSnippetEvent(Consumer)}
+ * and {@link jdk.jshell.JShell#onShutdown(java.util.function.Consumer) onShutdown(Consumer)}, which
+ * are unregistered with
+ * {@link jdk.jshell.JShell#unsubscribe(jdk.jshell.JShell.Subscription) unsubscribe(Subscription)}.
+ * Access to the source analysis utilities is via
+ * {@link jdk.jshell.JShell#sourceCodeAnalysis()}.
+ * When complete the instance should be closed to free resources --
+ * {@link jdk.jshell.JShell#close()}.
+ * <p>
+ * An instance of <code>JShell</code> is created with
+ * <code>JShell.create()</code>.
+ * <p>
+ * This class is not thread safe, except as noted, all access should be through
+ * a single thread.
+ * @see jdk.jshell
+ * @author Robert Field
+ */
+public class JShell implements AutoCloseable {
+
+    final SnippetMaps maps;
+    final KeyMap keyMap;
+    final TaskFactory taskFactory;
+    final InputStream in;
+    final PrintStream out;
+    final PrintStream err;
+    final Supplier<String> tempVariableNameGenerator;
+    final BiFunction<Snippet, Integer, String> idGenerator;
+
+    private int nextKeyIndex = 1;
+
+    final Eval eval;
+    final ClassTracker classTracker;
+    private final Map<Subscription, Consumer<JShell>> shutdownListeners = new HashMap<>();
+    private final Map<Subscription, Consumer<SnippetEvent>> keyStatusListeners = new HashMap<>();
+    private boolean closed = false;
+
+
+    private ExecutionControl executionControl = null;
+    private SourceCodeAnalysis sourceCodeAnalysis = null;
+
+
+    JShell(Builder b) {
+        this.in = b.in;
+        this.out = b.out;
+        this.err = b.err;
+        this.tempVariableNameGenerator = b.tempVariableNameGenerator;
+        this.idGenerator = b.idGenerator;
+
+        this.maps = new SnippetMaps(this);
+        maps.setPackageName("REPL");
+        this.keyMap = new KeyMap(this);
+        this.taskFactory = new TaskFactory(this);
+        this.eval = new Eval(this);
+        this.classTracker = new ClassTracker(this);
+    }
+
+    /**
+     * Builder for <code>JShell</code> instances.
+     * Create custom instances of <code>JShell</code> by using the setter
+     * methods on this class.  After zero or more of these, use the
+     * {@link #build()} method to create a <code>JShell</code> instance.
+     * These can all be chained. For example, setting the remote output and
+     * error streams:
+     * <pre>
+     * <code>
+     *     JShell myShell =
+     *       JShell.builder()
+     *         .out(myOutStream)
+     *         .err(myErrStream)
+     *         .build(); </code> </pre>
+     * If no special set-up is needed, just use
+     * <code>JShell.builder().build()</code> or the short-cut equivalent
+     * <code>JShell.create()</code>.
+     */
+    public static class Builder {
+
+        InputStream in = new ByteArrayInputStream(new byte[0]);
+        PrintStream out = System.out;
+        PrintStream err = System.err;
+        Supplier<String> tempVariableNameGenerator = null;
+        BiFunction<Snippet, Integer, String> idGenerator = null;
+
+        Builder() { }
+
+        /**
+         * Input for the running evaluation (it's <code>System.in</code>). Note:
+         * applications that use <code>System.in</code> for snippet or other
+         * user input cannot use <code>System.in</code> as the input stream for
+         * the remote process.
+         * <p>
+         * The default, if this is not set, is to provide an empty input stream
+         * -- <code>new ByteArrayInputStream(new byte[0])</code>.
+         *
+         * @param in the <code>InputStream</code> to be channelled to
+         * <code>System.in</code> in the remote execution process.
+         * @return the <code>Builder</code> instance (for use in chained
+         * initialization).
+         */
+        public Builder in(InputStream in) {
+            this.in = in;
+            return this;
+        }
+
+        /**
+         * Output for the running evaluation (it's <code>System.out</code>).
+         * The controlling process and
+         * the remote process can share <code>System.out</code>.
+         * <p>
+         * The default, if this is not set, is <code>System.out</code>.
+         *
+         * @param out the <code>PrintStream</code> to be channelled to
+         * <code>System.out</code> in the remote execution process.
+         * @return the <code>Builder</code> instance (for use in chained
+         * initialization).
+         */
+        public Builder out(PrintStream out) {
+            this.out = out;
+            return this;
+        }
+
+        /**
+         * Error output for the running evaluation (it's
+         * <code>System.err</code>). The controlling process and the remote
+         * process can share <code>System.err</code>.
+         * <p>
+         * The default, if this is not set, is <code>System.err</code>.
+         *
+         * @param err the <code>PrintStream</code> to be channelled to
+         * <code>System.err</code> in the remote execution process.
+         * @return the <code>Builder</code> instance (for use in chained
+         * initialization).
+         */
+        public Builder err(PrintStream err) {
+            this.err = err;
+            return this;
+        }
+
+        /**
+         * Set a generator of temp variable names for
+         * {@link jdk.jshell.VarSnippet} of
+         * {@link jdk.jshell.Snippet.SubKind#TEMP_VAR_EXPRESSION_SUBKIND}.
+         * <p>
+         * Do not use this method unless you have explicit need for it.
+         * <p>
+         * The generator will be used for newly created VarSnippet
+         * instances. The name of a variable is queried with
+         * {@link jdk.jshell.VarSnippet#name()}.
+         * <p>
+         * The callback is sent during the processing of the snippet, the
+         * JShell state is not stable. No calls whatsoever on the
+         * <code>JShell</code> instance may be made from the callback.
+         * <p>
+         * The generated name must be unique within active snippets.
+         * <p>
+         * The default behavior (if this is not set or <code>generator</code>
+         * is null) is to generate the name as a sequential number with a
+         * prefixing dollar sign ("$").
+         *
+         * @param generator the <code>Supplier</code> to generate the temporary
+         * variable name string or <code>null</code>.
+         * @return the <code>Builder</code> instance (for use in chained
+         * initialization).
+         */
+        public Builder tempVariableNameGenerator(Supplier<String> generator) {
+            this.tempVariableNameGenerator = generator;
+            return this;
+        }
+
+        /**
+         * Set the generator of identifying names for Snippets.
+         * <p>
+         * Do not use this method unless you have explicit need for it.
+         * <p>
+         * The generator will be used for newly created Snippet instances. The
+         * identifying name (id) is accessed with
+         * {@link jdk.jshell.Snippet#id()} and can be seen in the
+         * <code>StackTraceElement.getFileName()</code> for a
+         * {@link jdk.jshell.EvalException} and
+         * {@link jdk.jshell.UnresolvedReferenceException}.
+         * <p>
+         * The inputs to the generator are the {@link jdk.jshell.Snippet} and an
+         * integer. The integer will be the same for two Snippets which would
+         * overwrite one-another, but otherwise is unique.
+         * <p>
+         * The callback is sent during the processing of the snippet and the
+         * Snippet and the state as a whole are not stable. No calls to change
+         * system state (including Snippet state) should be made. Queries of
+         * Snippet may be made except to {@link jdk.jshell.Snippet#id()}. No
+         * calls on the <code>JShell</code> instance may be made from the
+         * callback, except to
+         * {@link #status(jdk.jshell.Snippet) status(Snippet)}.
+         * <p>
+         * The default behavior (if this is not set or <code>generator</code>
+         * is null) is to generate the id as the integer converted to a string.
+         *
+         * @param generator the <code>BiFunction</code> to generate the id
+         * string or <code>null</code>.
+         * @return the <code>Builder</code> instance (for use in chained
+         * initialization).
+         */
+        public Builder idGenerator(BiFunction<Snippet, Integer, String> generator) {
+            this.idGenerator = generator;
+            return this;
+        }
+
+        /**
+         * Build a JShell state engine. This is the entry-point to all JShell
+         * functionality. This creates a remote process for execution. It is
+         * thus important to close the returned instance.
+         *
+         * @return the state engine.
+         */
+        public JShell build() {
+            return new JShell(this);
+        }
+    }
+
+    // --- public API ---
+
+    /**
+     * Create a new JShell state engine.
+     * That is, create an instance of <code>JShell</code>.
+     * <p>
+     * Equivalent to {@link JShell#builder() JShell.builder()}{@link JShell.Builder#build() .build()}.
+     * @return an instance of <code>JShell</code>.
+     */
+    public static JShell create() {
+        return builder().build();
+    }
+
+    /**
+     * Factory method for <code>JShell.Builder</code> which, in-turn, is used
+     * for creating instances of <code>JShell</code>.
+     * Create a default instance of <code>JShell</code> with
+     * <code>JShell.builder().build()</code>. For more construction options
+     * see {@link jdk.jshell.JShell.Builder}.
+     * @return an instance of <code>Builder</code>.
+     * @see jdk.jshell.JShell.Builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Access to source code analysis functionality.
+     * An instance of <code>JShell</code> will always return the same
+     * <code>SourceCodeAnalysis</code> instance from
+     * <code>sourceCodeAnalysis()</code>.
+     * @return an instance of {@link SourceCodeAnalysis SourceCodeAnalysis}
+     * which can be used for source analysis such as completion detection and
+     * completion suggestions.
+     */
+    public SourceCodeAnalysis sourceCodeAnalysis() {
+        if (sourceCodeAnalysis == null) {
+            sourceCodeAnalysis = new SourceCodeAnalysisImpl(this);
+        }
+        return sourceCodeAnalysis;
+    }
+
+    /**
+     * Evaluate the input String, including definition and/or execution, if
+     * applicable. The input is checked for errors, unless the errors can be
+     * deferred (as is the case with some unresolvedDependencies references),
+     * errors will abort evaluation. The input should be
+     * exactly one complete snippet of source code, that is, one expression,
+     * statement, variable declaration, method declaration, class declaration,
+     * or import.
+     * To break arbitrary input into individual complete snippets, use
+     * {@link SourceCodeAnalysis#analyzeCompletion(String)}.
+     * <p>
+     * For imports, the import is added.  Classes, interfaces. methods,
+     * and variables are defined.  The initializer of variables, statements,
+     * and expressions are executed.
+     * The modifiers public, protected, private, static, and final are not
+     * allowed on op-level declarations and are ignored with a warning.
+     * Synchronized, native, abstract, and default top-level methods are not
+     * allowed and are errors.
+     * If a previous definition of a declaration is overwritten then there will
+     * be an event showing its status changed to OVERWRITTEN, this will not
+     * occur for dropped, rejected, or already overwritten declarations.
+     * <p>
+     * The execution environment is out of process.  If the evaluated code
+     * causes the execution environment to terminate, this <code>JShell</code>
+     * instance will be closed but the calling process and VM remain valid.
+     * @param input The input String to evaluate
+     * @return the list of events directly or indirectly caused by this evaluation.
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     * @see SourceCodeAnalysis#analyzeCompletion(String)
+     * @see JShell#onShutdown(java.util.function.Consumer)
+     */
+    public List<SnippetEvent> eval(String input) throws IllegalStateException {
+        checkIfAlive();
+        List<SnippetEvent> events = eval.eval(input);
+        events.forEach(this::notifyKeyStatusEvent);
+        return Collections.unmodifiableList(events);
+    }
+
+    /**
+     * Remove a declaration from the state.
+     * @param snippet The snippet to remove
+     * @return The list of events from updating declarations dependent on the
+     * dropped snippet.
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     * @throws IllegalArgumentException if the snippet is not associated with
+     * this <code>JShell</code> instance.
+     */
+    public List<SnippetEvent> drop(PersistentSnippet snippet) throws IllegalStateException {
+        checkIfAlive();
+        checkValidSnippet(snippet);
+        List<SnippetEvent> events = eval.drop(snippet);
+        events.forEach(this::notifyKeyStatusEvent);
+        return Collections.unmodifiableList(events);
+    }
+
+    /**
+     * The specified path is added to the end of the classpath used in eval().
+     * Note that the unnamed package is not accessible from the package in which
+     * {@link JShell#eval()} code is placed.
+     * @param path the path to add to the classpath.
+     */
+    public void addToClasspath(String path) {
+        taskFactory.addToClasspath(path);  // Compiler
+        executionControl().commandAddToClasspath(path);       // Runtime
+    }
+
+    /**
+     * Attempt to stop currently running evaluation. When called while
+     * the {@link #eval(java.lang.String) } method is running and the
+     * user's code being executed, an attempt will be made to stop user's code.
+     * Note that typically this method needs to be called from a different thread
+     * than the one running the {@code eval} method.
+     * <p>
+     * If the {@link #eval(java.lang.String) } method is not running, does nothing.
+     * <p>
+     * The attempt to stop the user's code may fail in some case, which may include
+     * when the execution is blocked on an I/O operation, or when the user's code is
+     * catching the {@link ThreadDeath} exception.
+     */
+    public void stop() {
+        if (executionControl != null)
+            executionControl.commandStop();
+    }
+
+    /**
+     * Close this state engine. Frees resources. Should be called when this
+     * state engine is no longer needed.
+     */
+    @Override
+    public void close() {
+        if (!closed) {
+            closeDown();
+            executionControl().commandExit();
+        }
+    }
+
+    /**
+     * Return all snippets.
+     * @return the snippets for all current snippets in id order.
+     * @throws IllegalStateException if this JShell instance is closed.
+     */
+    public List<Snippet> snippets() throws IllegalStateException {
+        checkIfAlive();
+        return Collections.unmodifiableList(maps.snippetList());
+    }
+
+    /**
+     * Returns the active variable snippets.
+     * This convenience method is equivalent to <code>snippets()</code> filtered for
+     * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
+     * <code>&amp;&amp; snippet.kind() == Kind.VARIABLE</code>
+     * and cast to <code>VarSnippet</code>.
+     * @return the active declared variables.
+     * @throws IllegalStateException if this JShell instance is closed.
+     */
+    public List<VarSnippet> variables() throws IllegalStateException {
+        return snippets().stream()
+                     .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.VAR)
+                     .map(sn -> (VarSnippet) sn)
+                     .collect(collectingAndThen(toList(), Collections::unmodifiableList));
+    }
+
+    /**
+     * Returns the active method snippets.
+     * This convenience method is equivalent to <code>snippets()</code> filtered for
+     * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
+     * <code>&amp;&amp; snippet.kind() == Kind.METHOD</code>
+     * and cast to MethodSnippet.
+     * @return the active declared methods.
+     * @throws IllegalStateException if this JShell instance is closed.
+     */
+    public List<MethodSnippet> methods() throws IllegalStateException {
+        return snippets().stream()
+                     .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.METHOD)
+                     .map(sn -> (MethodSnippet)sn)
+                     .collect(collectingAndThen(toList(), Collections::unmodifiableList));
+    }
+
+    /**
+     * Returns the active type declaration (class, interface, annotation type, and enum) snippets.
+     * This convenience method is equivalent to <code>snippets()</code> filtered for
+     * {@link jdk.jshell.Snippet.Status#isActive status(snippet).isActive}
+     * <code>&amp;&amp; snippet.kind() == Kind.TYPE_DECL</code>
+     * and cast to TypeDeclSnippet.
+     * @return the active declared type declarations.
+     * @throws IllegalStateException if this JShell instance is closed.
+     */
+    public List<TypeDeclSnippet> types() throws IllegalStateException {
+        return snippets().stream()
+                .filter(sn -> status(sn).isActive && sn.kind() == Snippet.Kind.TYPE_DECL)
+                .map(sn -> (TypeDeclSnippet) sn)
+                .collect(collectingAndThen(toList(), Collections::unmodifiableList));
+    }
+
+    /**
+     * Return the status of the snippet.
+     * This is updated either because of an explicit <code>eval()</code> call or
+     * an automatic update triggered by a dependency.
+     * @param snippet the <code>Snippet</code> to look up
+     * @return the status corresponding to this snippet
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     * @throws IllegalArgumentException if the snippet is not associated with
+     * this <code>JShell</code> instance.
+     */
+    public Status status(Snippet snippet) {
+        return checkValidSnippet(snippet).status();
+    }
+
+    /**
+     * Return the diagnostics of the most recent evaluation of the snippet.
+     * The evaluation can either because of an explicit <code>eval()</code> call or
+     * an automatic update triggered by a dependency.
+     * @param snippet the <code>Snippet</code> to look up
+     * @return the diagnostics corresponding to this snippet.  This does not
+     * include unresolvedDependencies references reported in <code>unresolvedDependencies()</code>.
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     * @throws IllegalArgumentException if the snippet is not associated with
+     * this <code>JShell</code> instance.
+     */
+    public List<Diag> diagnostics(Snippet snippet) {
+        return Collections.unmodifiableList(checkValidSnippet(snippet).diagnostics());
+    }
+
+    /**
+     * For {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED} or
+     * {@link jdk.jshell.Snippet.Status#RECOVERABLE_NOT_DEFINED RECOVERABLE_NOT_DEFINED}
+     * declarations, the names of current unresolved dependencies for
+     * the snippet.
+     * The returned value of this method, for a given method may change when an
+     * <code>eval()</code> or <code>drop()</code> of another snippet causes
+     * an update of a dependency.
+     * @param snippet the declaration <code>Snippet</code> to look up
+     * @return the list of symbol names that are currently unresolvedDependencies.
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     * @throws IllegalArgumentException if the snippet is not associated with
+     * this <code>JShell</code> instance.
+     */
+    public List<String> unresolvedDependencies(DeclarationSnippet snippet) {
+        return Collections.unmodifiableList(checkValidSnippet(snippet).unresolved());
+    }
+
+    /**
+     * Get the current value of a variable.
+     * @param snippet the variable Snippet whose value is queried.
+     * @return the current value of the variable referenced by snippet.
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     * @throws IllegalArgumentException if the snippet is not associated with
+     * this <code>JShell</code> instance.
+     * @throws IllegalArgumentException if the variable's status is anything but
+     * {@link jdk.jshell.Snippet.Status#VALID}.
+     */
+    public String varValue(VarSnippet snippet) throws IllegalStateException {
+        checkIfAlive();
+        checkValidSnippet(snippet);
+        if (snippet.status() != Status.VALID) {
+            throw new IllegalArgumentException("Snippet parameter of varValue() '" +
+                    snippet + "' must be VALID, it is: " + snippet.status());
+        }
+        String value = executionControl().commandVarValue(maps.classFullName(snippet), snippet.name());
+        return expunge(value);
+    }
+
+    /**
+     * Register a callback to be called when the Status of a snippet changes.
+     * Each call adds a new subscription.
+     * @param listener Action to perform when the Status changes.
+     * @return A token which can be used to {@linkplain JShell#unsubscribe unsubscribe} this subscription.
+     * @throws IllegalStateException if this <code>JShell</code> instance is closed.
+     */
+    public Subscription onSnippetEvent(Consumer<SnippetEvent> listener)
+            throws IllegalStateException {
+        return onX(keyStatusListeners, listener);
+    }
+
+    /**
+     * Register a callback to be called when this JShell instance terminates.
+     * This occurs either because the client process has ended (e.g. called System.exit(0))
+     * or the connection has been shutdown, as by close().
+     * Each call adds a new subscription.
+     * @param listener Action to perform when the state terminates.
+     * @return A token which can be used to {@linkplain JShell#unsubscribe unsubscribe} this subscription.
+     * @throws IllegalStateException if this JShell instance is closed
+     */
+    public Subscription onShutdown(Consumer<JShell> listener)
+            throws IllegalStateException {
+        return onX(shutdownListeners, listener);
+    }
+
+    /**
+     * Cancel a callback subscription.
+     * @param token The token corresponding to the subscription to be unsubscribed.
+     */
+    public void unsubscribe(Subscription token) {
+        synchronized (this) {
+            token.remover.accept(token);
+        }
+    }
+
+    /**
+     * Subscription is a token for referring to subscriptions so they can
+     * be {@linkplain JShell#unsubscribe unsubscribed}.
+     */
+    public class Subscription {
+
+        Consumer<Subscription> remover;
+
+        Subscription(Consumer<Subscription> remover) {
+            this.remover = remover;
+        }
+    }
+
+    // --- private / package-private implementation support ---
+
+    ExecutionControl executionControl() {
+        if (executionControl == null) {
+            this.executionControl = new ExecutionControl(new JDIEnv(this), maps, this);
+            try {
+                executionControl.launch();
+            } catch (IOException ex) {
+                throw new InternalError("Launching JDI execution engine threw: " + ex.getMessage(), ex);
+            }
+        }
+        return executionControl;
+    }
+
+    void debug(int flags, String format, Object... args) {
+        if (InternalDebugControl.debugEnabled(this, flags)) {
+            err.printf(format, args);
+        }
+    }
+
+    void debug(Exception ex, String where) {
+        if (InternalDebugControl.debugEnabled(this, 0xFFFFFFFF)) {
+            err.printf("Fatal error: %s: %s\n", where, ex.getMessage());
+            ex.printStackTrace(err);
+        }
+    }
+
+    /**
+     * Generate the next key index, indicating a unique snippet signature.
+     * @return the next key index
+     */
+    int nextKeyIndex() {
+        return nextKeyIndex++;
+    }
+
+    private synchronized <T> Subscription onX(Map<Subscription, Consumer<T>> map, Consumer<T> listener)
+            throws IllegalStateException {
+        Objects.requireNonNull(listener);
+        checkIfAlive();
+        Subscription token = new Subscription(map::remove);
+        map.put(token, listener);
+        return token;
+    }
+
+    private synchronized void notifyKeyStatusEvent(SnippetEvent event) {
+        keyStatusListeners.values().forEach(l -> l.accept(event));
+    }
+
+    private synchronized void notifyShutdownEvent(JShell state) {
+        shutdownListeners.values().forEach(l -> l.accept(state));
+    }
+
+    void closeDown() {
+        if (!closed) {
+            // Send only once
+            closed = true;
+            notifyShutdownEvent(this);
+        }
+    }
+
+    /**
+     * Check if this JShell has been closed
+     * @throws IllegalStateException if it is closed
+     */
+    private void checkIfAlive()  throws IllegalStateException {
+        if (closed) {
+            throw new IllegalStateException("JShell (" + this + ") has been closed.");
+        }
+    }
+
+    /**
+     * Check a Snippet parameter coming from the API user
+     * @param sn the Snippet to check
+     * @throws NullPointerException if Snippet parameter is null
+     * @throws IllegalArgumentException if Snippet is not from this JShell
+     * @return the input Snippet (for chained calls)
+     */
+    private Snippet checkValidSnippet(Snippet sn) {
+        if (sn == null) {
+            throw new NullPointerException("Snippet must not be null");
+        } else {
+            if (sn.key().state() != this) {
+                throw new IllegalArgumentException("Snippet not from this JShell");
+            }
+            return sn;
+        }
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java
new file mode 100644
index 0000000..5779493
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import jdk.jshell.Snippet.Kind;
+import jdk.jshell.Snippet.SubKind;
+
+/**
+ * The Key is unique for a given signature.  Used internal to the implementation
+ * to group signature matched Snippets.  Snippet kinds without a signature
+ * (for example expressions) each have their own UniqueKey.
+ * @author Robert Field
+ */
+abstract class Key {
+
+    /**
+     * The unique index for this Key
+     */
+    private final int index;
+
+    /**
+     * The JShell corresponding to this Key
+     */
+    private final JShell state;
+
+    Key(JShell state) {
+        this.index = state.nextKeyIndex();
+        this.state = state;
+    }
+
+    /**
+     * The unique numeric identifier for the snippet.  Snippets which replace or
+     * redefine existing snippets take on the same key index as the replaced or
+     * redefined snippet.
+     * The index values are monotonically increasing integers.
+     * @return the Key index
+     */
+    int index() { return index; }
+
+    /**
+     * The kind for the key.  Indicates the subinterface of Key.
+     * @return the Kind of the Key
+     */
+    abstract Kind kind();
+
+    /**
+     * For foreign key testing.
+     */
+    JShell state() { return state; }
+
+    /**
+     * Grouping for snippets which persist and influence future code.
+     * They are keyed off at least the name.  They may be Modified/Replaced
+     * with new input and can be dropped (JShell#drop).
+     */
+    static abstract class PersistentKey extends Key {
+
+        private final String name;
+
+        PersistentKey(JShell state, String name) {
+            super(state);
+            this.name = name;
+        }
+        /**
+         * Name of the snippet.
+         *
+         * @return the name of the snippet.
+         */
+        String name() { return name; }
+    }
+
+    /**
+     * Grouping for snippets which reference declarations
+     */
+    static abstract class DeclarationKey extends PersistentKey {
+
+        DeclarationKey(JShell state, String name) {
+            super(state, name);
+        }
+    }
+
+    /**
+     * Key for a class definition Keys of TYPE_DECL. Keyed off class name.
+     */
+    static class TypeDeclKey extends DeclarationKey {
+
+        TypeDeclKey(JShell state, String name) {
+            super(state, name);
+        }
+
+        @Override
+        Kind kind() { return Kind.TYPE_DECL; }
+
+        @Override
+        public String toString() { return "ClassKey(" + name() + ")#" + index(); }
+    }
+
+    /**
+     * Key for a method definition Keys of METHOD. Keyed off method name and
+     * parameter types.
+     */
+    static class MethodKey extends DeclarationKey {
+
+        private final String parameterTypes;
+
+        MethodKey(JShell state, String name, String parameterTypes) {
+            super(state, name);
+            this.parameterTypes = parameterTypes;
+        }
+
+        @Override
+        Kind kind() { return Kind.METHOD; }
+
+        /**
+         * The parameter types of the method. Because of overloading of methods,
+         * the parameter types are part of the key.
+         *
+         * @return a String representation of the parameter types of the method.
+         */
+        String parameterTypes() { return parameterTypes; }
+
+
+        @Override
+        public String toString() { return "MethodKey(" + name() +
+                "(" + parameterTypes() + "))#" + index(); }
+    }
+
+    /**
+     * Key for a variable definition Keys of VARIABLE. Keyed off variable
+     * name.
+     */
+    static class VarKey extends DeclarationKey {
+
+        VarKey(JShell state, String name) {
+            super(state, name);
+        }
+
+        @Override
+        public Kind kind() { return Kind.VAR; }
+
+        @Override
+        public String toString() { return "VariableKey(" + name() + ")#" + index(); }
+    }
+
+    /**
+     * Key for an import. Keys of IMPORT. Keyed off import text and whether
+     * import is static.
+     */
+    static class ImportKey extends PersistentKey {
+
+        private final SubKind snippetKind;
+
+        ImportKey(JShell state, String name,SubKind snippetKind) {
+            super(state, name);
+            this.snippetKind = snippetKind;
+        }
+
+        @Override
+        public Kind kind() { return Kind.IMPORT; }
+
+        /**
+         * Which kind of import.
+         *
+         * @return the appropriate SubKind.
+         */
+        SubKind snippetKind() {
+            return snippetKind;
+        }
+
+
+        @Override
+        public String toString() { return "ImportKey(" + name() + "," +
+                snippetKind + ")#" + index(); }
+    }
+
+    /**
+     * Grouping for snippets which are the key for only one input -- even if the
+     * exactly same entry is made again. The referenced snippets are thus
+     * unmodifiable.
+     */
+    static abstract class UniqueKey extends Key {
+
+        UniqueKey(JShell state) {
+            super(state);
+        }
+    }
+
+    /**
+     * Key for a statement snippet. Keys of STATEMENT. Uniquely keyed, see
+     * UniqueKey.
+     */
+    static class StatementKey extends UniqueKey {
+
+        StatementKey(JShell state) {
+            super(state);
+        }
+
+
+        @Override
+        public Kind kind() {
+            return Kind.STATEMENT;
+        }
+
+        @Override
+        public String toString() { return "StatementKey#" + index(); }
+    }
+
+    /**
+     * Key for an expression. Keys of EXPRESSION. Uniquely keyed, see
+     * UniqueKey.
+     */
+    static class ExpressionKey extends UniqueKey {
+
+        private final String name;
+        private final String typeName;
+
+        ExpressionKey(JShell state, String name, String typeName) {
+            super(state);
+            this.name = name;
+            this.typeName = typeName;
+        }
+
+        @Override
+        public Kind kind() { return Kind.EXPRESSION; }
+
+
+        /**
+         * Variable name which is the value of the expression. Since the
+         * expression is either just an identifier which is a variable or it is
+         * an assignment to a variable, there is always a variable which is the
+         * subject of the expression. All other expression snippets become
+         * temporary variables referenced by a VariableKey.
+         *
+         * @return the name of the variable which is the subject of the
+         * expression.
+         */
+        String name() { return name; }
+
+        /**
+         * Type of the expression
+         *
+         * @return String representation of the type of the expression.
+         */
+        String typeName() { return typeName; }
+
+
+        @Override
+        public String toString() { return "ExpressionKey(" + name() + ")#" + index(); }
+    }
+
+    /**
+     * Key for an erroneous snippet. Keys of ERRONEOUS. Uniquely keyed, see
+     * UniqueKey.
+     */
+    static class ErroneousKey extends UniqueKey {
+
+        ErroneousKey(JShell state) {
+            super(state);
+        }
+
+        @Override
+        Kind kind() { return Kind.ERRONEOUS; }
+
+        @Override
+        public String toString() { return "ErroneousKey#" + index(); }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/KeyMap.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/KeyMap.java
new file mode 100644
index 0000000..8b9db67
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/KeyMap.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Stream;
+import jdk.jshell.Key.TypeDeclKey;
+import jdk.jshell.Key.ErroneousKey;
+import jdk.jshell.Key.ExpressionKey;
+import jdk.jshell.Key.ImportKey;
+import jdk.jshell.Key.MethodKey;
+import jdk.jshell.Key.StatementKey;
+import jdk.jshell.Key.VarKey;
+import jdk.jshell.Snippet.SubKind;
+import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
+
+/**
+ * Maps signature to Key by Kind.
+ * @author Robert Field
+ */
+class KeyMap {
+    private final JShell state;
+
+    KeyMap(JShell state) {
+        this.state = state;
+    }
+
+    private final Map<String, TypeDeclKey> classMap = new LinkedHashMap<>();
+    private final Map<String, MethodKey> methodMap = new LinkedHashMap<>();
+    private final Map<String, VarKey> varMap = new LinkedHashMap<>();
+    private final Map<String, ImportKey> importMap = new LinkedHashMap<>();
+
+    TypeDeclKey keyForClass(String name) {
+        return classMap.computeIfAbsent(name, k -> new TypeDeclKey(state, name));
+    }
+
+    MethodKey keyForMethod(String name, String parameterTypes) {
+        return methodMap.computeIfAbsent(name + ":" + parameterTypes,
+                                         k -> new MethodKey(state, name, parameterTypes));
+    }
+
+    VarKey keyForVariable(String name) {
+        return varMap.computeIfAbsent(name, k -> new VarKey(state, name));
+    }
+
+    ImportKey keyForImport(String name, SubKind snippetKind) {
+        return importMap.computeIfAbsent(name + ":"
+                + ((snippetKind == SINGLE_TYPE_IMPORT_SUBKIND || snippetKind == SINGLE_STATIC_IMPORT_SUBKIND)
+                        ? "single"
+                        : snippetKind.toString()),
+                k -> new ImportKey(state, name, snippetKind));
+    }
+
+    StatementKey keyForStatement() {
+        return new StatementKey(state);
+    }
+
+    ExpressionKey keyForExpression(String name, String type) {
+        return new ExpressionKey(state, name, type);
+    }
+
+    ErroneousKey keyForErroneous() {
+        return new ErroneousKey(state);
+    }
+
+    boolean doesVariableNameExist(String name) {
+        return varMap.get(name) != null;
+    }
+
+    Stream<ImportKey> importKeys() {
+        return importMap.values().stream();
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MaskCommentsAndModifiers.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MaskCommentsAndModifiers.java
new file mode 100644
index 0000000..da4665d
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MaskCommentsAndModifiers.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Within a String, mask code comments and ignored modifiers (within context).
+ *
+ * @author Robert Field
+ */
+class MaskCommentsAndModifiers {
+
+    private final static Set<String> IGNORED_MODIFERS =
+            Stream.of( "public", "protected", "private", "static", "final" )
+                    .collect( Collectors.toSet() );
+
+    private final StringBuilder sbCleared = new StringBuilder();
+    private final StringBuilder sbMask = new StringBuilder();
+    private final String str;
+    private final int length;
+    private final boolean maskModifiers;
+    private int next = 0;
+    private boolean wasMasked = false;
+    private boolean inside = false;
+
+    @SuppressWarnings("empty-statement")
+    public MaskCommentsAndModifiers(String s, boolean maskModifiers) {
+        this.str = s;
+        this.length = s.length();
+        this.maskModifiers = maskModifiers;
+        do { } while (next());
+    }
+
+    public String cleared() {
+        return sbCleared.toString();
+    }
+
+    public String mask() {
+        return sbMask.toString();
+    }
+
+    public boolean wasMasked() {
+        return wasMasked;
+    }
+
+    /**
+     * Read the next character
+     */
+    private int read() {
+        if (next >= length) {
+            return -1;
+        }
+        return str.charAt(next++);
+    }
+
+    private void write(StringBuilder sb, int ch) {
+        sb.append((char)ch);
+    }
+
+    private void write(int ch) {
+        write(sbCleared, ch);
+        write(sbMask, Character.isWhitespace(ch) ? ch : ' ');
+    }
+
+    private void writeMask(int ch) {
+        wasMasked = true;
+        write(sbMask, ch);
+        write(sbCleared, Character.isWhitespace(ch) ? ch : ' ');
+    }
+
+    private void write(CharSequence s) {
+        for (int cp : s.chars().toArray()) {
+            write(cp);
+        }
+    }
+
+    private void writeMask(CharSequence s) {
+        for (int cp : s.chars().toArray()) {
+            writeMask(cp);
+        }
+    }
+
+    private boolean next() {
+        return next(read());
+    }
+
+    private boolean next(int c) {
+        if (c < 0) {
+            return false;
+        }
+
+        if (c == '\'' || c == '"') {
+            inside = true;
+            write(c);
+            int match = c;
+            c = read();
+            while (c != match) {
+                if (c < 0) {
+                    return false;
+                }
+                if (c == '\n' || c == '\r') {
+                    write(c);
+                    return true;
+                }
+                if (c == '\\') {
+                    write(c);
+                    c = read();
+                }
+                write(c);
+                c = read();
+            }
+            write(c);
+            return true;
+        }
+
+        if (c == '/') {
+            c = read();
+            if (c == '*') {
+                writeMask('/');
+                writeMask(c);
+                int prevc = 0;
+                while ((c = read()) != '/' || prevc != '*') {
+                    if (c < 0) {
+                        return false;
+                    }
+                    writeMask(c);
+                    prevc = c;
+                }
+                writeMask(c);
+                return true;
+            } else if (c == '/') {
+                writeMask('/');
+                writeMask(c);
+                while ((c = read()) != '\n' && c != '\r') {
+                    if (c < 0) {
+                        return false;
+                    }
+                    writeMask(c);
+                }
+                writeMask(c);
+                return true;
+            } else {
+                inside = true;
+                write('/');
+                // read character falls through
+            }
+        }
+
+        if (Character.isJavaIdentifierStart(c)) {
+            if (maskModifiers && !inside) {
+                StringBuilder sb = new StringBuilder();
+                do {
+                    write(sb, c);
+                    c = read();
+                } while (Character.isJavaIdentifierPart(c));
+                String id = sb.toString();
+                if (IGNORED_MODIFERS.contains(id)) {
+                    writeMask(sb);
+                } else {
+                    write(sb);
+                    if (id.equals("import")) {
+                        inside = true;
+                    }
+                }
+                return next(c); // recurse to handle left-over character
+            }
+        } else if (!Character.isWhitespace(c)) {
+            inside = true;
+        }
+
+        if (c < 0) {
+            return false;
+        }
+        write(c);
+        return true;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java
new file mode 100644
index 0000000..5fdf1b7
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java
@@ -0,0 +1,651 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.tools.JavaFileObject.Kind;
+import static javax.tools.StandardLocation.CLASS_PATH;
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_FMGR;
+
+/**
+ * File manager for the compiler API.  Reads from memory (Strings) and writes
+ * class files to memory (cached OutputMemoryJavaFileObject).
+ *
+ * @author Robert Field
+ */
+class MemoryFileManager implements JavaFileManager {
+
+    private final StandardJavaFileManager stdFileManager;
+
+    private final Map<String, OutputMemoryJavaFileObject> classObjects = new TreeMap<>();
+
+    private ClassFileCreationListener classListener = null;
+
+    private final ClassLoader loader = new REPLClassLoader();
+
+    private final JShell proc;
+
+    // Upcoming Jigsaw
+    private Method inferModuleNameMethod = null;
+    private Method listModuleLocationsMethod = null;
+
+    static abstract class MemoryJavaFileObject extends SimpleJavaFileObject {
+
+        public MemoryJavaFileObject(String name, JavaFileObject.Kind kind) {
+            super(URI.create("string:///" + name.replace('.', '/')
+                    + kind.extension), kind);
+        }
+    }
+
+    class SourceMemoryJavaFileObject extends MemoryJavaFileObject {
+        private final String src;
+        private final Object origin;
+
+        SourceMemoryJavaFileObject(Object origin, String className, String code) {
+            super(className, JavaFileObject.Kind.SOURCE);
+            this.origin = origin;
+            this.src = code;
+        }
+
+        public Object getOrigin() {
+            return origin;
+        }
+
+        @Override @DefinedBy(Api.COMPILER)
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return src;
+        }
+    }
+
+    static class OutputMemoryJavaFileObject extends MemoryJavaFileObject {
+
+        /**
+         * Byte code created by the compiler will be stored in this
+         * ByteArrayOutputStream.
+         */
+        private ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        private byte[] bytes = null;
+
+        private final String className;
+
+        public OutputMemoryJavaFileObject(String name, JavaFileObject.Kind kind) {
+            super(name, kind);
+            this.className = name;
+        }
+
+        public byte[] getBytes() {
+            if (bytes == null) {
+                bytes = bos.toByteArray();
+                bos = null;
+            }
+            return bytes;
+        }
+
+        public void dump() {
+            try {
+                Path dumpDir = FileSystems.getDefault().getPath("dump");
+                if (Files.notExists(dumpDir)) {
+                    Files.createDirectory(dumpDir);
+                }
+                Path file = FileSystems.getDefault().getPath("dump", getName() + ".class");
+                Files.write(file, getBytes());
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        @Override @DefinedBy(Api.COMPILER)
+        public String getName() {
+            return className;
+        }
+
+        /**
+         * Will provide the compiler with an output stream that leads to our
+         * byte array.
+         */
+        @Override @DefinedBy(Api.COMPILER)
+        public OutputStream openOutputStream() throws IOException {
+            return bos;
+        }
+
+        @Override @DefinedBy(Api.COMPILER)
+        public InputStream openInputStream() throws IOException {
+            return new ByteArrayInputStream(getBytes());
+        }
+    }
+
+    // For restoring process-local execution support
+    class REPLClassLoader extends ClassLoader {
+
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            OutputMemoryJavaFileObject fo = classObjects.get(name);
+            proc.debug(DBG_FMGR, "findClass %s = %s\n", name, fo);
+            if (fo == null) {
+                throw new ClassNotFoundException("Not ours");
+            }
+            byte[] b = fo.getBytes();
+            return super.defineClass(name, b, 0, b.length, null);
+        }
+    }
+
+    public MemoryFileManager(StandardJavaFileManager standardManager, JShell proc) {
+        this.stdFileManager = standardManager;
+        this.proc = proc;
+    }
+
+    private Collection<OutputMemoryJavaFileObject> generatedClasses() {
+        return classObjects.values();
+    }
+
+    // For debugging dumps
+    public void dumpClasses() {
+        for (OutputMemoryJavaFileObject co : generatedClasses()) {
+            co.dump();
+        }
+    }
+
+    // For restoring process-local execution support
+    public Class<?> findGeneratedClass(String genClassFullName) throws ClassNotFoundException {
+        for (OutputMemoryJavaFileObject co : generatedClasses()) {
+            if (co.className.equals(genClassFullName)) {
+                Class<?> klass = loadClass(co.className);
+                proc.debug(DBG_FMGR, "Loaded %s\n", klass);
+                return klass;
+            }
+        }
+        return null;
+    }
+
+    // For restoring process-local execution support
+    public byte[] findGeneratedBytes(String genClassFullName) throws ClassNotFoundException {
+        for (OutputMemoryJavaFileObject co : generatedClasses()) {
+            if (co.className.equals(genClassFullName)) {
+                return co.getBytes();
+            }
+        }
+        return null;
+    }
+
+    // For restoring process-local execution support
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        return getClassLoader(null).loadClass(name);
+    }
+
+    public JavaFileObject createSourceFileObject(Object origin, String name, String code) {
+        return new SourceMemoryJavaFileObject(origin, name, code);
+    }
+
+    // Make compatible with Jigsaw
+    public String inferModuleName(Location location) {
+        try {
+            if (inferModuleNameMethod == null) {
+                inferModuleNameMethod = JavaFileManager.class.getDeclaredMethod("inferModuleName", Location.class);
+            }
+            @SuppressWarnings("unchecked")
+            String result = (String) inferModuleNameMethod.invoke(stdFileManager, location);
+            return result;
+        } catch (NoSuchMethodException | SecurityException ex) {
+            throw new InternalError("Cannot lookup JavaFileManager method", ex);
+        } catch (IllegalAccessException |
+                IllegalArgumentException |
+                InvocationTargetException ex) {
+            throw new InternalError("Cannot invoke JavaFileManager method", ex);
+        }
+    }
+
+    // Make compatible with Jigsaw
+    public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
+        try {
+            if (listModuleLocationsMethod == null) {
+                listModuleLocationsMethod = JavaFileManager.class.getDeclaredMethod("listModuleLocations", Location.class);
+            }
+            @SuppressWarnings("unchecked")
+            Iterable<Set<Location>> result = (Iterable<Set<Location>>) listModuleLocationsMethod.invoke(stdFileManager, location);
+            return result;
+        } catch (NoSuchMethodException | SecurityException ex) {
+            throw new InternalError("Cannot lookup JavaFileManager method", ex);
+        } catch (IllegalAccessException |
+                IllegalArgumentException |
+                InvocationTargetException ex) {
+            throw new InternalError("Cannot invoke JavaFileManager method", ex);
+        }
+    }
+
+
+    /**
+     * Returns a class loader for loading plug-ins from the given location. For
+     * example, to load annotation processors, a compiler will request a class
+     * loader for the {@link
+     * StandardLocation#ANNOTATION_PROCESSOR_PATH
+     * ANNOTATION_PROCESSOR_PATH} location.
+     *
+     * @param location a location
+     * @return a class loader for the given location; or {@code null}
+     * if loading plug-ins from the given location is disabled or if
+     * the location is not known
+     * @throws SecurityException if a class loader can not be created
+     * in the current security context
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public ClassLoader getClassLoader(JavaFileManager.Location location) {
+        proc.debug(DBG_FMGR, "getClassLoader: location\n", location);
+        return loader;
+    }
+
+    /**
+     * Lists all file objects matching the given criteria in the given
+     * location.  List file objects in "subpackages" if recurse is
+     * true.
+     *
+     * <p>Note: even if the given location is unknown to this file
+     * manager, it may not return {@code null}.  Also, an unknown
+     * location may not cause an exception.
+     *
+     * @param location     a location
+     * @param packageName  a package name
+     * @param kinds        return objects only of these kinds
+     * @param recurse      if true include "subpackages"
+     * @return an Iterable of file objects matching the given criteria
+     * @throws IOException if an I/O error occurred, or if {@link
+     * #close} has been called and this file manager cannot be
+     * reopened
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public Iterable<JavaFileObject> list(JavaFileManager.Location location,
+            String packageName,
+            Set<JavaFileObject.Kind> kinds,
+            boolean recurse)
+            throws IOException {
+        Iterable<JavaFileObject> stdList = stdFileManager.list(location, packageName, kinds, recurse);
+        if (location==CLASS_PATH && packageName.equals("REPL")) {
+            // if the desired list is for our JShell package, lazily iterate over
+            // first the standard list then any generated classes.
+            return () -> new Iterator<JavaFileObject>() {
+                boolean stdDone = false;
+                Iterator<? extends JavaFileObject> it;
+
+                @Override
+                public boolean hasNext() {
+                    if (it == null) {
+                        it = stdList.iterator();
+                    }
+                    if (it.hasNext()) {
+                        return true;
+                    }
+                    if (stdDone) {
+                        return false;
+                    } else {
+                        stdDone = true;
+                        it = generatedClasses().iterator();
+                        return it.hasNext();
+                    }
+                }
+
+                @Override
+                public JavaFileObject next() {
+                    if (!hasNext()) {
+                        throw new NoSuchElementException();
+                    }
+                    return it.next();
+                }
+
+            };
+        } else {
+            return stdList;
+        }
+    }
+
+    /**
+     * Infers a binary name of a file object based on a location.  The
+     * binary name returned might not be a valid binary name according to
+     * <cite>The Java&trade {        throw new UnsupportedOperationException("Not supported yet.");  } Language Specification</cite>.
+     *
+     * @param location a location
+     * @param file a file object
+     * @return a binary name or {@code null} the file object is not
+     * found in the given location
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public String inferBinaryName(JavaFileManager.Location location, JavaFileObject file) {
+        if (file instanceof OutputMemoryJavaFileObject) {
+            OutputMemoryJavaFileObject ofo = (OutputMemoryJavaFileObject) file;
+            proc.debug(DBG_FMGR, "inferBinaryName %s => %s\n", file, ofo.getName());
+            return ofo.getName();
+        } else {
+            return stdFileManager.inferBinaryName(location, file);
+        }
+    }
+
+    /**
+     * Compares two file objects and return true if they represent the
+     * same underlying object.
+     *
+     * @param a a file object
+     * @param b a file object
+     * @return true if the given file objects represent the same
+     * underlying object
+     *
+     * @throws IllegalArgumentException if either of the arguments
+     * were created with another file manager and this file manager
+     * does not support foreign file objects
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public boolean isSameFile(FileObject a, FileObject b) {
+        return stdFileManager.isSameFile(b, b);
+    }
+
+    /**
+     * Determines if the given option is supported and if so, the
+     * number of arguments the option takes.
+     *
+     * @param option an option
+     * @return the number of arguments the given option takes or -1 if
+     * the option is not supported
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public int isSupportedOption(String option) {
+        proc.debug(DBG_FMGR, "isSupportedOption: %s\n", option);
+        return stdFileManager.isSupportedOption(option);
+    }
+
+    /**
+     * Handles one option.  If {@code current} is an option to this
+     * file manager it will consume any arguments to that option from
+     * {@code remaining} and return true, otherwise return false.
+     *
+     * @param current current option
+     * @param remaining remaining options
+     * @return true if this option was handled by this file manager,
+     * false otherwise
+     * @throws IllegalArgumentException if this option to this file
+     * manager is used incorrectly
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public boolean handleOption(String current, Iterator<String> remaining) {
+        proc.debug(DBG_FMGR, "handleOption: current: %s\n", current +
+                ", remaining: " + remaining);
+        return stdFileManager.handleOption(current, remaining);
+    }
+
+    /**
+     * Determines if a location is known to this file manager.
+     *
+     * @param location a location
+     * @return true if the location is known
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public boolean hasLocation(JavaFileManager.Location location) {
+        proc.debug(DBG_FMGR, "hasLocation: location: %s\n", location);
+        return stdFileManager.hasLocation(location);
+    }
+
+    interface ClassFileCreationListener {
+        void newClassFile(OutputMemoryJavaFileObject jfo, JavaFileManager.Location location,
+                String className, Kind kind, FileObject sibling);
+    }
+
+    void registerClassFileCreationListener(ClassFileCreationListener listen) {
+        this.classListener = listen;
+    }
+
+    /**
+     * Returns a {@linkplain JavaFileObject file object} for input
+     * representing the specified class of the specified kind in the
+     * given location.
+     *
+     * @param location a location
+     * @param className the name of a class
+     * @param kind the kind of file, must be one of {@link
+     * JavaFileObject.Kind#SOURCE SOURCE} or {@link
+     * JavaFileObject.Kind#CLASS CLASS}
+     * @return a file object, might return {@code null} if the
+     * file does not exist
+     * @throws IllegalArgumentException if the location is not known
+     * to this file manager and the file manager does not support
+     * unknown locations, or if the kind is not valid
+     * @throws IOException if an I/O error occurred, or if {@link
+     * #close} has been called and this file manager cannot be
+     * reopened
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public JavaFileObject getJavaFileForInput(JavaFileManager.Location location,
+            String className,
+            JavaFileObject.Kind kind)
+            throws IOException {
+        return stdFileManager.getJavaFileForInput(location, className, kind);
+    }
+
+    /**
+     * Returns a {@linkplain JavaFileObject file object} for output
+     * representing the specified class of the specified kind in the
+     * given location.
+     *
+     * <p>Optionally, this file manager might consider the sibling as
+     * a hint for where to place the output.  The exact semantics of
+     * this hint is unspecified.  The JDK compiler, javac, for
+     * example, will place class files in the same directories as
+     * originating source files unless a class file output directory
+     * is provided.  To facilitate this behavior, javac might provide
+     * the originating source file as sibling when calling this
+     * method.
+     *
+     * @param location a location
+     * @param className the name of a class
+     * @param kind the kind of file, must be one of {@link
+     * JavaFileObject.Kind#SOURCE SOURCE} or {@link
+     * JavaFileObject.Kind#CLASS CLASS}
+     * @param sibling a file object to be used as hint for placement;
+     * might be {@code null}
+     * @return a file object for output
+     * @throws IllegalArgumentException if sibling is not known to
+     * this file manager, or if the location is not known to this file
+     * manager and the file manager does not support unknown
+     * locations, or if the kind is not valid
+     * @throws IOException if an I/O error occurred, or if {@link
+     * #close} has been called and this file manager cannot be
+     * reopened
+     * @throws IllegalStateException {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location,
+            String className, Kind kind, FileObject sibling) throws IOException {
+
+        OutputMemoryJavaFileObject fo;
+        fo = new OutputMemoryJavaFileObject(className, kind);
+        classObjects.put(className, fo);
+        proc.debug(DBG_FMGR, "Set out file: %s = %s\n", className, fo);
+        if (classListener != null) {
+            classListener.newClassFile(fo, location, className, kind, sibling);
+        }
+        return fo;
+    }
+
+    /**
+     * Returns a {@linkplain FileObject file object} for input
+     * representing the specified <a href="JavaFileManager.html#relative_name">relative
+     * name</a> in the specified package in the given location.
+     *
+     * <p>If the returned object represents a {@linkplain
+     * JavaFileObject.Kind#SOURCE source} or {@linkplain
+     * JavaFileObject.Kind#CLASS class} file, it must be an instance
+     * of {@link JavaFileObject}.
+     *
+     * <p>Informally, the file object returned by this method is
+     * located in the concatenation of the location, package name, and
+     * relative name.  For example, to locate the properties file
+     * "resources/compiler.properties" in the package
+     * "com.sun.tools.javac" in the {@linkplain
+     * StandardLocation#SOURCE_PATH SOURCE_PATH} location, this method
+     * might be called like so:
+     *
+     * <pre>getFileForInput(SOURCE_PATH, "com.sun.tools.javac", "resources/compiler.properties");</pre>
+     *
+     * <p>If the call was executed on Windows, with SOURCE_PATH set to
+     * <code>"C:\Documents&nbsp;and&nbsp;Settings\UncleBob\src\share\classes"</code>,
+     * a valid result would be a file object representing the file
+     * <code>"C:\Documents&nbsp;and&nbsp;Settings\UncleBob\src\share\classes\com\sun\tools\javac\resources\compiler.properties"</code>.
+     *
+     * @param location a location
+     * @param packageName a package name
+     * @param relativeName a relative name
+     * @return a file object, might return {@code null} if the file
+     * does not exist
+     * @throws IllegalArgumentException if the location is not known
+     * to this file manager and the file manager does not support
+     * unknown locations, or if {@code relativeName} is not valid
+     * @throws IOException if an I/O error occurred, or if {@link
+     * #close} has been called and this file manager cannot be
+     * reopened
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public FileObject getFileForInput(JavaFileManager.Location location,
+            String packageName,
+            String relativeName)
+            throws IOException {
+        proc.debug(DBG_FMGR, "getFileForInput location=%s packageName=%s\n", location, packageName);
+        return stdFileManager.getFileForInput(location, packageName, relativeName);
+    }
+
+    /**
+     * Returns a {@linkplain FileObject file object} for output
+     * representing the specified <a href="JavaFileManager.html#relative_name">relative
+     * name</a> in the specified package in the given location.
+     *
+     * <p>Optionally, this file manager might consider the sibling as
+     * a hint for where to place the output.  The exact semantics of
+     * this hint is unspecified.  The JDK compiler, javac, for
+     * example, will place class files in the same directories as
+     * originating source files unless a class file output directory
+     * is provided.  To facilitate this behavior, javac might provide
+     * the originating source file as sibling when calling this
+     * method.
+     *
+     * <p>If the returned object represents a {@linkplain
+     * JavaFileObject.Kind#SOURCE source} or {@linkplain
+     * JavaFileObject.Kind#CLASS class} file, it must be an instance
+     * of {@link JavaFileObject}.
+     *
+     * <p>Informally, the file object returned by this method is
+     * located in the concatenation of the location, package name, and
+     * relative name or next to the sibling argument.  See {@link
+     * #getFileForInput getFileForInput} for an example.
+     *
+     * @param location a location
+     * @param packageName a package name
+     * @param relativeName a relative name
+     * @param sibling a file object to be used as hint for placement;
+     * might be {@code null}
+     * @return a file object
+     * @throws IllegalArgumentException if sibling is not known to
+     * this file manager, or if the location is not known to this file
+     * manager and the file manager does not support unknown
+     * locations, or if {@code relativeName} is not valid
+     * @throws IOException if an I/O error occurred, or if {@link
+     * #close} has been called and this file manager cannot be
+     * reopened
+     * @throws IllegalStateException if {@link #close} has been called
+     * and this file manager cannot be reopened
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public FileObject getFileForOutput(JavaFileManager.Location location,
+            String packageName,
+            String relativeName,
+            FileObject sibling)
+            throws IOException {
+        throw new UnsupportedOperationException("getFileForOutput: location: " + location +
+                ", packageName: " + packageName +
+                ", relativeName: " + relativeName +
+                ", sibling: " + sibling);
+    }
+
+    /**
+     * Flushes any resources opened for output by this file manager
+     * directly or indirectly.  Flushing a closed file manager has no
+     * effect.
+     *
+     * @throws IOException if an I/O error occurred
+     * @see #close
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public void flush() throws IOException {
+        // Nothing to flush
+    }
+
+    /**
+     * Releases any resources opened by this file manager directly or
+     * indirectly.  This might render this file manager useless and
+     * the effect of subsequent calls to methods on this object or any
+     * objects obtained through this object is undefined unless
+     * explicitly allowed.  However, closing a file manager which has
+     * already been closed has no effect.
+     *
+     * @throws IOException if an I/O error occurred
+     * @see #flush
+     */
+    @Override @DefinedBy(Api.COMPILER)
+    public void close() throws IOException {
+        // Nothing to close
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java
new file mode 100644
index 0000000..e707570
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.Collection;
+import jdk.jshell.Key.MethodKey;
+
+/**
+ * Snippet for a method definition.
+ * The Kind is {@link jdk.jshell.Snippet.Kind#METHOD}.
+ * <p>
+ * <code>MethodSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ * @jls 8.4: MethodDeclaration.
+ */
+public class MethodSnippet extends DeclarationSnippet {
+
+    final String signature;
+    private String qualifiedParamaterTypes;
+
+    MethodSnippet(MethodKey key, String userSource, Wrap guts,
+            String name, String signature, Wrap corralled,
+            Collection<String> declareReferences, Collection<String> bodyReferences) {
+        super(key, userSource, guts, name, SubKind.METHOD_SUBKIND, corralled, declareReferences, bodyReferences);
+        this.signature = signature;
+    }
+
+    /**
+     * A String representation of the parameter types of the method.
+     * @return a comma separated list of user entered parameter types for the
+     * method.
+     */
+    public String parameterTypes() {
+        return key().parameterTypes();
+    }
+
+    /**
+     * The full type signature of the method, including return type.
+     * @return A String representation of the parameter and return types
+     */
+    public String signature() {
+        return signature;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("MethodSnippet:");
+        sb.append(name());
+        sb.append('/');
+        sb.append(signature());
+        sb.append('-');
+        sb.append(source());
+        return sb.toString();
+    }
+
+    /**** internal access ****/
+
+    @Override
+    MethodKey key() {
+        return (MethodKey) super.key();
+    }
+
+    String qualifiedParameterTypes() {
+        return qualifiedParamaterTypes;
+    }
+
+    void setQualifiedParamaterTypes(String sig) {
+        qualifiedParamaterTypes = sig;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java
new file mode 100644
index 0000000..2d08f38
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import jdk.jshell.Wrap.CompoundWrap;
+import static jdk.jshell.Util.*;
+import java.util.Locale;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
+
+/**
+ *
+ * @author Robert Field
+ */
+final class OuterWrap implements GeneralWrap {
+
+    private final String packageName;
+    private final String className;
+    private final String userSource;
+    private final GeneralWrap w;
+    private final Wrap guts;
+
+    public static OuterWrap wrapInClass(String packageName, String className,
+             String imports, String userSource, Wrap guts) {
+        GeneralWrap kw = new CompoundWrap(
+                imports
+                + "class " + className + " {\n",
+                guts,
+                "}\n");
+        return new OuterWrap(packageName, className, userSource, kw, guts);
+    }
+
+    public static OuterWrap wrapImport(String userSource, Wrap guts) {
+        return new OuterWrap("", "", userSource, guts, guts);
+    }
+
+    private OuterWrap(String packageName, String className, String userSource,
+            GeneralWrap w, Wrap guts) {
+        this.packageName = packageName;
+        this.className = className;
+        this.userSource = userSource;
+        this.w = w;
+        this.guts = guts;
+    }
+
+    @Override
+    public final String wrapped() {
+        return w.wrapped();
+    }
+
+    @Override
+    public int snippetIndexToWrapIndex(int ui) {
+        return w.snippetIndexToWrapIndex(ui);
+    }
+
+    @Override
+    public int wrapIndexToSnippetIndex(int si) {
+        return w.wrapIndexToSnippetIndex(si);
+    }
+
+    @Override
+    public int firstSnippetIndex() {
+        return w.firstSnippetIndex();
+    }
+
+    @Override
+    public int lastSnippetIndex() {
+        return w.lastSnippetIndex();
+    }
+
+    @Override
+    public int snippetLineToWrapLine(int snline) {
+        return w.snippetLineToWrapLine(snline);
+    }
+
+    @Override
+    public int wrapLineToSnippetLine(int wline) {
+        return w.wrapLineToSnippetLine(wline);
+    }
+
+    @Override
+    public int firstSnippetLine() {
+        return w.firstSnippetLine();
+    }
+
+    @Override
+    public int lastSnippetLine() {
+        return w.lastSnippetLine();
+    }
+
+    public String className() {
+        return className;
+    }
+
+    public String classFullName() {
+        return packageName + "." + className;
+    }
+
+    public String getUserSource() {
+        return userSource;
+    }
+
+    Wrap guts() {
+        return guts;
+    }
+
+    Diag wrapDiag(Diagnostic<? extends JavaFileObject> d) {
+        return new WrappedDiagnostic(d);
+    }
+
+    class WrappedDiagnostic extends Diag {
+
+        private final Diagnostic<? extends JavaFileObject> diag;
+
+        WrappedDiagnostic(Diagnostic<? extends JavaFileObject> diag) {
+            this.diag = diag;
+        }
+
+        @Override
+        public boolean isError() {
+            return diag.getKind() == Diagnostic.Kind.ERROR;
+        }
+
+        @Override
+        public long getPosition() {
+            return wrapIndexToSnippetIndex(diag.getPosition());
+        }
+
+        @Override
+        public long getStartPosition() {
+            return wrapIndexToSnippetIndex(diag.getStartPosition());
+        }
+
+        @Override
+        public long getEndPosition() {
+            return wrapIndexToSnippetIndex(diag.getEndPosition());
+        }
+
+        @Override
+        public String getCode() {
+            return diag.getCode();
+        }
+
+        @Override
+        public String getMessage(Locale locale) {
+            return expunge(diag.getMessage(locale));
+        }
+
+        @Override
+        Unit unitOrNull() {
+            JavaFileObject fo = diag.getSource();
+            if (fo instanceof SourceMemoryJavaFileObject) {
+                SourceMemoryJavaFileObject sfo = (SourceMemoryJavaFileObject) fo;
+                if (sfo.getOrigin() instanceof Unit) {
+                    return (Unit) sfo.getOrigin();
+                }
+            }
+            return null;
+        }
+
+    @Override
+    public String toString() {
+        return "WrappedDiagnostic(" + getMessage(null) + ":" + getPosition() + ")";
+    }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java
new file mode 100644
index 0000000..84a9fa7
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+/**
+ * Grouping for Snippets which persist and influence future code.
+ * A persistent snippet can be
+ * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten)}
+ * with new input and can be dropped {@link JShell#drop}.
+ * <p>
+ * <code>PersistentSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ */
+public abstract class PersistentSnippet extends Snippet {
+
+    PersistentSnippet(Key key, String userSource, Wrap guts, String unitName, SubKind subkind) {
+        super(key, userSource, guts, unitName, subkind);
+    }
+
+    /**
+     * Name of the Snippet.
+     *
+     * @return the name of the snippet.
+     */
+    @Override
+    public String name() {
+        return unitName;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java
new file mode 100644
index 0000000..7411ec9
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import com.sun.tools.javac.code.TypeTag;
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
+import com.sun.tools.javac.parser.Tokens.Token;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.CLASS;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.COLON;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.ENUM;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.EOF;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.INTERFACE;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.LPAREN;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.MONKEYS_AT;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.PACKAGE;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.SEMI;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.VOID;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
+import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
+import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.JCTree.Tag;
+import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Position;
+
+/**
+ * This is a subclass of JavacParser which overrides one method with a modified
+ * verson of that method designed to allow parsing of one "snippet" of Java
+ * code without the surrounding context of class, method, etc.
+ * Accepts an expression, a statement, an import, or the declaration of a
+ * method, variable, or type (class, interface, ...).
+ */
+class ReplParser extends JavacParser {
+
+    public ReplParser(ParserFactory fac,
+            com.sun.tools.javac.parser.Lexer S,
+            boolean keepDocComments,
+            boolean keepLineMap,
+            boolean keepEndPositions) {
+        super(fac, S, keepDocComments, keepLineMap, keepEndPositions);
+    }
+
+    /**
+     * As faithful a clone of the overridden method as possible while still
+     * achieving the goal of allowing the parse of a stand-alone snippet.
+     * As a result, some variables are assigned and never used, tests are
+     * always true, loops don't, etc.  This is to allow easy transition as the
+     * underlying method changes.
+     * @return a snippet wrapped in a compilation unit
+     */
+    @Override
+    public JCCompilationUnit parseCompilationUnit() {
+        Token firstToken = token;
+        JCModifiers mods = null;
+        boolean seenImport = false;
+        boolean seenPackage = false;
+        ListBuffer<JCTree> defs = new ListBuffer<>();
+        if (token.kind == MONKEYS_AT) {
+            mods = modifiersOpt();
+        }
+
+        if (token.kind == PACKAGE) {
+            int packagePos = token.pos;
+            List<JCAnnotation> annotations = List.nil();
+            seenPackage = true;
+            if (mods != null) {
+                checkNoMods(mods.flags);
+                annotations = mods.annotations;
+                mods = null;
+            }
+            nextToken();
+            JCExpression pid = qualident(false);
+            accept(SEMI);
+            JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
+            attach(pd, firstToken.comment(CommentStyle.JAVADOC));
+            storeEnd(pd, token.pos);
+            defs.append(pd);
+        }
+
+        boolean firstTypeDecl = true;
+        while (token.kind != EOF) {
+            if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
+                // error recovery
+                skip(true, false, false, false);
+                if (token.kind == EOF) {
+                    break;
+                }
+            }
+            if (mods == null && token.kind == IMPORT) {
+                seenImport = true;
+                defs.append(importDeclaration());
+            } else {
+                Comment docComment = token.comment(CommentStyle.JAVADOC);
+                if (firstTypeDecl && !seenImport && !seenPackage) {
+                    docComment = firstToken.comment(CommentStyle.JAVADOC);
+                }
+                List<? extends JCTree> udefs = replUnit(mods, docComment);
+               // if (def instanceof JCExpressionStatement)
+                //     def = ((JCExpressionStatement)def).expr;
+                for (JCTree def : udefs) {
+                    defs.append(def);
+                }
+                mods = null;
+                firstTypeDecl = false;
+            }
+            break;  // Remove to process more than one snippet
+        }
+        List<JCTree> rdefs = defs.toList();
+        class ReplUnit extends JCCompilationUnit {
+
+            public ReplUnit(List<JCTree> defs) {
+                super(defs);
+            }
+        }
+        JCCompilationUnit toplevel = new ReplUnit(rdefs);
+        if (rdefs.isEmpty()) {
+            storeEnd(toplevel, S.prevToken().endPos);
+        }
+        toplevel.lineMap = S.getLineMap();
+        this.endPosTable.setParser(null); // remove reference to parser
+        toplevel.endPositions = this.endPosTable;
+        return toplevel;
+    }
+
+    @SuppressWarnings("fallthrough")
+     List<? extends JCTree> replUnit(JCModifiers pmods, Comment dc) {
+        switch (token.kind) {
+            case EOF:
+                return List.nil();
+            case RBRACE:
+            case CASE:
+            case DEFAULT:
+                // These are illegal, fall through to handle as illegal statement
+            case LBRACE:
+            case IF:
+            case FOR:
+            case WHILE:
+            case DO:
+            case TRY:
+            case SWITCH:
+            case RETURN:
+            case THROW:
+            case BREAK:
+            case CONTINUE:
+            case SEMI:
+            case ELSE:
+            case FINALLY:
+            case CATCH:
+            case ASSERT:
+                return List.<JCTree>of(parseStatement());
+            case SYNCHRONIZED:
+                if (peekToken(LPAREN)) {
+                    return List.<JCTree>of(parseStatement());
+                }
+                //fall-through
+            default:
+                JCModifiers mods = modifiersOpt(pmods);
+                if (token.kind == CLASS
+                        || token.kind == INTERFACE
+                        || token.kind == ENUM) {
+                    return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
+                } else {
+                    int pos = token.pos;
+                    List<JCTypeParameter> typarams = typeParametersOpt();
+                    // if there are type parameters but no modifiers, save the start
+                    // position of the method in the modifiers.
+                    if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
+                        mods.pos = pos;
+                        storeEnd(mods, pos);
+                    }
+                    List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
+
+                    if (annosAfterParams.nonEmpty()) {
+                        checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
+                        mods.annotations = mods.annotations.appendList(annosAfterParams);
+                        if (mods.pos == Position.NOPOS) {
+                            mods.pos = mods.annotations.head.pos;
+                        }
+                    }
+
+                    Token prevToken = token;
+                    pos = token.pos;
+                    JCExpression t;
+                    boolean isVoid = token.kind == VOID;
+                    if (isVoid) {
+                        t = to(F.at(pos).TypeIdent(TypeTag.VOID));
+                        nextToken();
+                    } else {
+                        // return type of method, declared type of variable, or an expression
+                        t = term(EXPR | TYPE);
+                    }
+                    if (token.kind == COLON && t.hasTag(IDENT)) {
+                        // labelled statement
+                        nextToken();
+                        JCStatement stat = parseStatement();
+                        return List.<JCTree>of(F.at(pos).Labelled(prevToken.name(), stat));
+                    } else if ((isVoid || (lastmode & TYPE) != 0) && LAX_IDENTIFIER.accepts(token.kind)) {
+                        // we have "Type Ident", so we can assume it is variable or method declaration
+                        pos = token.pos;
+                        Name name = ident();
+                        if (token.kind == LPAREN) {
+                        // method declaration
+                            //mods.flags |= Flags.STATIC;
+                            return List.of(methodDeclaratorRest(
+                                    pos, mods, t, name, typarams,
+                                    false, isVoid, dc));
+                        } else if (!isVoid && typarams.isEmpty()) {
+                        // variable declaration
+                            //mods.flags |= Flags.STATIC;
+                            List<JCTree> defs
+                                    = variableDeclaratorsRest(pos, mods, t, name, false, dc,
+                                            new ListBuffer<JCTree>()).toList();
+                            accept(SEMI);
+                            storeEnd(defs.last(), S.prevToken().endPos);
+                            return defs;
+                        } else {
+                            // malformed declaration, return error
+                            pos = token.pos;
+                            List<JCTree> err = isVoid
+                                    ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, t, typarams,
+                                                            List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
+                                    : null;
+                            return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
+                        }
+                    } else if (!typarams.isEmpty()) {
+                        // type parameters on non-variable non-method -- error
+                        return List.<JCTree>of(syntaxError(token.pos, "illegal.start.of.type"));
+                    } else {
+                        // expression-statement or expression to evaluate
+                        JCExpressionStatement expr = toP(F.at(pos).Exec(t));
+                        return List.<JCTree>of(expr);
+                    }
+
+                }
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java
new file mode 100644
index 0000000..1429973
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.util.Context;
+
+/**
+ *
+ * @author Robert Field
+ */
+class ReplParserFactory extends ParserFactory {
+
+    public static ParserFactory instance(Context context) {
+        ParserFactory instance = context.get(parserFactoryKey);
+        if (instance == null) {
+            instance = new ReplParserFactory(context);
+        }
+        return instance;
+    }
+
+    private final ScannerFactory scannerFactory;
+
+    protected ReplParserFactory(Context context) {
+        super(context);
+        this.scannerFactory = ScannerFactory.instance(context);
+    }
+
+    @Override
+    public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
+        com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
+        return new ReplParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplResolve.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplResolve.java
new file mode 100644
index 0000000..2472870
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplResolve.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.util.Context;
+
+/**
+ * Just need access to isStatic
+ */
+class ReplResolve extends Resolve {
+
+    ReplResolve(Context context) {
+        super(context);
+    }
+
+    public static boolean isStatic(Env<AttrContext> env) {
+        return Resolve.isStatic(env);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java
new file mode 100644
index 0000000..7c6968a
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java
@@ -0,0 +1,681 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import static jdk.jshell.Util.REPL_CLASS_PREFIX;
+import static jdk.jshell.Util.asLetters;
+
+/**
+ * A Snippet represents a snippet of Java source code as passed to
+ * {@link jdk.jshell.JShell#eval}.  It is associated only with the
+ * {@link jdk.jshell.JShell JShell} instance that created it.
+ * An instance of Snippet (including its subclasses) is immutable: an access to
+ * any of its methods will always return the same result.
+ * For information about the current state of the snippet within the JShell
+ * state engine, query <code>JShell</code> passing the Snippet.
+ * <p>
+ * Because it is immutable, <code>Snippet</code> (and subclasses) is thread-safe.
+ * @author Robert Field
+ * @see jdk.jshell.JShell#status
+ */
+public abstract class Snippet {
+
+    /**
+     * Describes the general kind of snippet.
+     * The <code>Kind</code> is an immutable property of a Snippet.
+     * It is accessed with {@link jdk.jshell.Snippet#kind()}.
+     * The <code>Kind</code> can be used to determine which
+     * subclass of Snippet it is. For example,
+     * {@link jdk.jshell.JShell#eval eval("int three() { return 3; }")} will
+     * return a snippet creation event.  The <code>Kind</code> of that Snippet
+     * will be <code>METHOD</code>, from which you know that the subclass
+     * of <code>Snippet</code> is <code>MethodSnippet</code> and it can be
+     * cast as such.
+     */
+    public enum Kind {
+        /**
+         * An import declaration: <code>import</code> ...
+         * The snippet is an instance of {@link jdk.jshell.ImportSnippet}.
+         * An import can be a single type import
+         * ({@link jdk.jshell.Snippet.SubKind#SINGLE_TYPE_IMPORT_SUBKIND}),
+         * a static single import
+         * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}),
+         * an on-demand type import
+         * ({@link jdk.jshell.Snippet.SubKind#TYPE_IMPORT_ON_DEMAND_SUBKIND}),
+         * or a static on-demand type import
+         * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}) --
+         * use {@link jdk.jshell.Snippet#subKind()} to distinguish.
+         * @jls 8.3: importDeclaration.
+         */
+        IMPORT(true),
+
+        /**
+         * A type declaration.
+         * Which includes: NormalClassDeclaration, EnumDeclaration,
+         * NormalInterfaceDeclaration, and AnnotationTypeDeclaration.
+         * The snippet is an instance of {@link jdk.jshell.TypeDeclSnippet}.
+         * A type declaration may be an interface
+         * {@link jdk.jshell.Snippet.SubKind#INTERFACE_SUBKIND},
+         * classes {@link jdk.jshell.Snippet.SubKind#CLASS_SUBKIND}, enums, and
+         * annotation interfaces -- see {@link jdk.jshell.Snippet.SubKind} to
+         * differentiate.
+         * @jls 7.6: TypeDeclaration.
+         */
+        TYPE_DECL(true),
+
+        /**
+         * A method declaration.
+         * The snippet is an instance of {@link jdk.jshell.MethodSnippet}.
+         * @jls 8.4: MethodDeclaration.
+         */
+        METHOD(true),
+
+        /**
+         * One variable declaration.
+         * Corresponding to one <i>VariableDeclarator</i>.
+         * The snippet is an instance of {@link jdk.jshell.VarSnippet}.
+         * The variable may be with or without initializer, or be a temporary
+         * variable representing an expression -- see
+         * {@link jdk.jshell.Snippet.SubKind}to differentiate.
+         * @jls 8.3: FieldDeclaration.
+         */
+        VAR(true),
+
+        /**
+         * An expression, with or without side-effects.
+         * The snippet is an instance of {@link jdk.jshell.ExpressionSnippet}.
+         * The expression is currently either a simple named reference to a
+         * variable ({@link jdk.jshell.Snippet.SubKind#VAR_VALUE_SUBKIND}) or an
+         * assignment (both of which have natural referencing
+         * names) -- see {@link jdk.jshell.Snippet.SubKind} to differentiate.
+         * @jls 15: Expression.
+         */
+        EXPRESSION(false),
+
+        /**
+         * A statement.
+         * The snippet is an instance of {@link jdk.jshell.StatementSnippet}.
+         * @jls 14.5: Statement.
+         */
+        STATEMENT(false),
+
+        /**
+         * A syntactically incorrect input for which the specific
+         * kind could not be determined.
+         * The snippet is an instance of {@link jdk.jshell.ErroneousSnippet}.
+         */
+        ERRONEOUS(false);
+
+        /**
+         * True if this kind of snippet adds a declaration or declarations
+         * which are visible to subsequent evaluations.
+         */
+        public final boolean isPersistent;
+
+        Kind(boolean isPersistent) {
+            this.isPersistent = isPersistent;
+        }
+    }
+
+    /**
+     * The detailed variety of a snippet.  This is a sub-classification of the
+     * Kind.  The Kind of a SubKind is accessible with
+     * {@link jdk.jshell.Snippet.SubKind#kind}.
+     */
+    public enum SubKind {
+
+        /**
+         * Single-Type-Import Declaration.
+         * An import declaration of a single type.
+         * @jls 7.5.1 SingleTypeImportDeclaration.
+         */
+        SINGLE_TYPE_IMPORT_SUBKIND(Kind.IMPORT),
+
+        /**
+         * Type-Import-on-Demand Declaration.
+         * A non-static "star" import.
+         * @jls 7.5.2. TypeImportOnDemandDeclaration.
+         */
+        TYPE_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT),
+
+        /**
+         * Single-Static-Import Declaration.
+         * An import of a static member.
+         * @jls 7.5.3 Single-Static-Import.
+         */
+        SINGLE_STATIC_IMPORT_SUBKIND(Kind.IMPORT),
+
+        /**
+         * Static-Import-on-Demand Declaration.
+         * A static "star" import of all static members of a named type.
+         * @jls 7.5.4. Static-Import-on-Demand Static "star" import.
+         */
+        STATIC_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT),
+
+        /**
+         * A class declaration.
+         * A <code>SubKind</code> of {@link Kind#TYPE_DECL}.
+         * @jls 8.1. NormalClassDeclaration.
+         */
+        CLASS_SUBKIND(Kind.TYPE_DECL),
+
+        /**
+         * An interface declaration.
+         * A <code>SubKind</code> of {@link Kind#TYPE_DECL}.
+         * @jls 9.1. NormalInterfaceDeclaration.
+         */
+        INTERFACE_SUBKIND(Kind.TYPE_DECL),
+
+        /**
+         * An enum declaration.
+         * A <code>SubKind</code> of {@link Kind#TYPE_DECL}.
+         * @jls 8.9. EnumDeclaration.
+         */
+        ENUM_SUBKIND(Kind.TYPE_DECL),
+
+        /**
+         * An annotation interface declaration. A <code>SubKind</code> of
+         * {@link Kind#TYPE_DECL}.
+         * @jls 9.6. AnnotationTypeDeclaration.
+         */
+        ANNOTATION_TYPE_SUBKIND(Kind.TYPE_DECL),
+
+        /**
+         * A method. The only <code>SubKind</code> for {@link Kind#METHOD}.
+         * @jls 8.4. MethodDeclaration.
+         */
+        METHOD_SUBKIND(Kind.METHOD),
+
+        /**
+         * A variable declaration without initializer.
+         * A <code>SubKind</code> of {@link Kind#VAR}.
+         * @jls 8.3. VariableDeclarator without VariableInitializer in
+         * FieldDeclaration.
+         */
+        VAR_DECLARATION_SUBKIND(Kind.VAR),
+
+        /**
+         * A variable declaration with an initializer expression. A
+         * <code>SubKind</code> of {@link Kind#VAR}.
+         * @jls 8.3. VariableDeclarator with VariableInitializer in
+         * FieldDeclaration.
+         */
+        VAR_DECLARATION_WITH_INITIALIZER_SUBKIND(Kind.VAR, true, true),
+
+        /**
+         * An expression whose value has been stored in a temporary variable. A
+         * <code>SubKind</code> of {@link Kind#VAR}.
+         * @jls 15. Primary.
+         */
+        TEMP_VAR_EXPRESSION_SUBKIND(Kind.VAR, true, true),
+
+        /**
+         * A simple variable reference expression. A <code>SubKind</code> of
+         * {@link Kind#EXPRESSION}.
+         * @jls 15.11. Field Access as 3.8. Identifier.
+         */
+        VAR_VALUE_SUBKIND(Kind.EXPRESSION, true, true),
+
+        /**
+         * An assignment expression. A <code>SubKind</code> of
+         * {@link Kind#EXPRESSION}.
+         * @jls 15.26. Assignment.
+         */
+        ASSIGNMENT_SUBKIND(Kind.EXPRESSION, true, true),
+
+        /**
+         * An expression which has not been wrapped in a temporary variable
+         * (reserved). A <code>SubKind</code> of {@link Kind#EXPRESSION}.
+         */
+        OTHER_EXPRESSION_SUBKIND(Kind.EXPRESSION, true, true),
+
+        /**
+         * A statement. The only <code>SubKind</code> for {@link Kind#STATEMENT}.
+         * @jls 14.5. Statement.
+         */
+        STATEMENT_SUBKIND(Kind.STATEMENT, true, false),
+
+        /**
+         * An unknown snippet. The only <code>SubKind</code> for
+         * {@link Kind#ERRONEOUS}.
+         */
+        UNKNOWN_SUBKIND(Kind.ERRONEOUS, false, false);
+
+        private final boolean isExecutable;
+        private final boolean hasValue;
+        private final Kind kind;
+
+        SubKind(Kind kind) {
+            this.kind = kind;
+            this.isExecutable = false;
+            this.hasValue = false;
+        }
+
+        SubKind(Kind kind, boolean isExecutable, boolean hasValue) {
+            this.kind = kind;
+            this.isExecutable = isExecutable;
+            this.hasValue = hasValue;
+        }
+
+        /**
+         * Is this <code>SubKind</code> executable?
+         *
+         * @return true if this <code>SubKind</code> can be executed.
+         */
+        public boolean isExecutable() {
+            return isExecutable;
+        }
+
+        /**
+         * Is this <code>SubKind</code> executable and is non-<code>void</code>.
+         *
+         * @return true if this <code>SubKind</code> has a value.
+         */
+        public boolean hasValue() {
+            return hasValue;
+        }
+
+        /**
+         * The {@link Snippet.Kind} that corresponds to this <code>SubKind</code>.
+         *
+         * @return the fixed <code>Kind</code> for this <code>SubKind</code>
+         */
+        public Kind kind() {
+            return kind;
+        }
+    }
+
+    /**
+     * Describes the current state of a Snippet.
+     * This is a dynamic property of a Snippet within the JShell state --
+     * thus is retrieved with a {@linkplain
+     * jdk.jshell.JShell#status(jdk.jshell.Snippet) query on <code>JShell</code>}.
+     * <p>
+     * The <code>Status</code> changes as the state changes.
+     * For example, creation of another snippet with
+     * {@link jdk.jshell.JShell#eval(java.lang.String) eval}
+     * may resolve dependencies of this Snippet (or invalidate those dependencies), or
+     * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwrite}
+     * this Snippet changing its
+     * <code>Status</code>.
+     * <p>
+     * Important properties associated with <code>Status</code> are:
+     * {@link jdk.jshell.Snippet.Status#isDefined}, if it is visible to other
+     * existing and new snippets; and
+     * {@link jdk.jshell.Snippet.Status#isActive}, if, as the
+     * JShell state changes, the snippet will update, possibly
+     * changing <code>Status</code>.
+     * An executable Snippet can only be executed if it is in the the
+     * {@link jdk.jshell.Snippet.Status#VALID} <code>Status</code>.
+     * @see JShell#status(jdk.jshell.Snippet)
+     */
+    public enum Status {
+        /**
+         * The snippet is a valid snippet
+         * (in the context of current <code>JShell</code> state).
+         * Only snippets with <code>VALID</code>
+         * <code>Status</code> can be executed (though not all
+         * <code>VALID</code> snippets have executable code).
+         * If the snippet is a declaration or import, it is visible to other
+         * snippets ({@link Status#isDefined isDefined} <code> == true</code>).
+         * <p>
+         * The snippet will update as dependents change
+         * ({@link Status#isActive isActive} <code> == true</code>), its
+         * status could become <code>RECOVERABLE_DEFINED</code>, <code>RECOVERABLE_NOT_DEFINED</code>,
+         * <code>DROPPED</code>, or <code>OVERWRITTEN</code>.
+         */
+        VALID(true, true),
+
+        /**
+         * The snippet is a declaration snippet with potentially recoverable
+         * unresolved references or other issues in its body
+         * (in the context of current <code>JShell</code> state).
+         * Only a {@link jdk.jshell.DeclarationSnippet} can have this
+         * <code>Status</code>.
+         * The snippet has a valid signature and it is visible to other
+         * snippets ({@link Status#isDefined isDefined} <code> == true</code>)
+         * and thus can be referenced in existing or new snippets
+         * but the snippet cannot be executed.
+         * An {@link UnresolvedReferenceException} will be thrown on an attempt
+         * to execute it.
+         * <p>
+         * The snippet will update as dependents change
+         * ({@link Status#isActive isActive} <code> == true</code>), its
+         * status could become <code>VALID</code>, <code>RECOVERABLE_NOT_DEFINED</code>,
+         * <code>DROPPED</code>, or <code>OVERWRITTEN</code>.
+         * <p>
+         * Note: both <code>RECOVERABLE_DEFINED</code> and <code>RECOVERABLE_NOT_DEFINED</code>
+         * indicate potentially recoverable errors, they differ in that, for
+         * <code>RECOVERABLE_DEFINED</code>, the snippet is
+         * {@linkplain Status#isDefined defined}.
+         */
+        RECOVERABLE_DEFINED(true, true),
+
+        /**
+         * The snippet is a declaration snippet with potentially recoverable
+         * unresolved references or other issues
+         * (in the context of current <code>JShell</code> state).
+         * Only a {@link jdk.jshell.DeclarationSnippet} can have this
+         * <code>Status</code>.
+         * The snippet has an invalid signature or the implementation is
+         * otherwise unable to define it.
+         * The snippet it is not visible to other snippets
+         * ({@link Status#isDefined isDefined} <code> == false</code>)
+         * and thus cannot be referenced or executed.
+         * <p>
+         * The snippet will update as dependents change
+         * ({@link Status#isActive isActive} <code> == true</code>), its
+         * status could become <code>VALID</code>, <code>RECOVERABLE_DEFINED</code>,
+         * <code>DROPPED</code>, or <code>OVERWRITTEN</code>.
+         * <p>
+         * Note: both <code>RECOVERABLE_DEFINED</code> and <code>RECOVERABLE_NOT_DEFINED</code>
+         * indicate potentially recoverable errors, they differ in that, for
+         * <code>RECOVERABLE_DEFINED</code>, the snippet is
+         * {@linkplain Status#isDefined defined}.
+         */
+        RECOVERABLE_NOT_DEFINED(true, false),
+
+        /**
+         * The snippet is inactive because of an explicit call to
+         * the {@link JShell#drop(jdk.jshell.PersistentSnippet)}.
+         * Only a {@link jdk.jshell.PersistentSnippet} can have this
+         * <code>Status</code>.
+         * The snippet is not visible to other snippets
+         * ({@link Status#isDefined isDefined} <code> == false</code>)
+         * and thus cannot be referenced or executed.
+         * <p>
+         * The snippet will not update as dependents change
+         * ({@link Status#isActive isActive} <code> == false</code>), its
+         * <code>Status</code> will never change again.
+         */
+        DROPPED(false, false),
+
+        /**
+         * The snippet is inactive because it has been replaced by a new
+         * snippet.  This occurs when the new snippet added with
+         * {@link jdk.jshell.JShell#eval} matches a previous snippet.
+         * A <code>TypeDeclSnippet</code> will match another
+         * <code>TypeDeclSnippet</code> if the names match.
+         * For example <code>class X { }</code> will overwrite
+         * <code>class X { int ii; }</code> or
+         * <code>interface X { }</code>.
+         * A <code>MethodSnippet</code> will match another
+         * <code>MethodSnippet</code> if the names and parameter types
+         * match.
+         * For example <code>void m(int a) { }</code> will overwrite
+         * <code>int m(int a) { return a+a; }</code>.
+         * A <code>VarSnippet</code> will match another
+         * <code>VarSnippet</code> if the names match.
+         * For example <code>double z;</code> will overwrite
+         * <code>long z = 2L;</code>.
+         * Only a {@link jdk.jshell.PersistentSnippet} can have this
+         * <code>Status</code>.
+         * The snippet is not visible to other snippets
+         * ({@link Status#isDefined isDefined} <code> == false</code>)
+         * and thus cannot be referenced or executed.
+         * <p>
+         * The snippet will not update as dependents change
+         * ({@link Status#isActive isActive} <code> == false</code>), its
+         * <code>Status</code> will never change again.
+         */
+        OVERWRITTEN(false, false),
+
+        /**
+         * The snippet is inactive because it failed compilation on initial
+         * evaluation and it is not capable of becoming valid with further
+         * changes to the JShell state.
+         * The snippet is not visible to other snippets
+         * ({@link Status#isDefined isDefined} <code> == false</code>)
+         * and thus cannot be referenced or executed.
+         * <p>
+         * The snippet will not update as dependents change
+         * ({@link Status#isActive isActive} <code> == false</code>), its
+         * <code>Status</code> will never change again.
+         */
+        REJECTED(false, false),
+
+        /**
+         * The snippet is inactive because it does not yet exist.
+         * Used only in {@link SnippetEvent#previousStatus} for new
+         * snippets.
+         * {@link jdk.jshell.JShell#status(jdk.jshell.Snippet) JShell.status(Snippet)}
+         * will never return this <code>Status</code>.
+         * Vacuously, {@link Status#isDefined isDefined} and
+         * {@link Status#isActive isActive} are both defined <code>false</code>.
+         */
+        NONEXISTENT(false, false);
+
+        /**
+         * Is the Snippet active, that is, will the snippet
+         * be re-evaluated when a new
+         * {@link JShell#eval(java.lang.String) JShell.eval(String)} or
+         * {@link JShell#drop(jdk.jshell.PersistentSnippet)
+         * JShell.drop(PersistentSnippet)} that could change
+         * its status is invoked?  This is more broad than
+         * {@link Status#isDefined} since a Snippet which is
+         * {@link Status#RECOVERABLE_NOT_DEFINED}
+         * will be updated.
+         */
+        public final boolean isActive;
+
+        /**
+         * Is the snippet currently part of the defined state of the JShell?
+         * Is it visible to compilation of other snippets?
+         */
+        public final boolean isDefined;
+
+        Status(boolean isActive, boolean isDefined) {
+            this.isActive = isActive;
+            this.isDefined = isDefined;
+        }
+    }
+
+    private final Key key;
+    private final String source;
+    private final Wrap guts;
+    final String unitName;
+    private final SubKind subkind;
+
+    private int seq;
+    private String className;
+    private String id;
+    private OuterWrap outer;
+    private Status status;
+    private List<String> unresolved;
+    private DiagList diagnostics;
+
+    Snippet(Key key, String userSource, Wrap guts, String unitName, SubKind subkind) {
+        this.key = key;
+        this.source = userSource;
+        this.guts = guts;
+        this.unitName = unitName;
+        this.subkind = subkind;
+        this.status = Status.NONEXISTENT;
+        setSequenceNumber(0);
+    }
+
+    /**** public access ****/
+
+    /**
+     * The unique identifier for the snippet. No two active snippets will have
+     * the same id().
+     * @return the snippet id string.
+     */
+    public String id() {
+        return id;
+    }
+
+    /**
+     * The {@link jdk.jshell.Snippet.Kind} for the snippet.
+     * Indicates the subclass of Snippet.
+     * @return the Kind of the snippet
+     * @see Snippet.Kind
+     */
+    public Kind kind() {
+        return subkind.kind();
+    }
+
+    /**
+     * Return the {@link SubKind} of snippet.
+     * The SubKind is useful for feedback to users.
+     * @return the SubKind corresponding to this snippet
+     */
+    public SubKind subKind() {
+        return subkind;
+    }
+
+    /**
+     * Return the source code of the snippet.
+     * @return the source code corresponding to this snippet
+     */
+    public String source() {
+        return source;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Snippet:");
+        if (key() != null) {
+            sb.append(key().toString());
+        }
+        sb.append('-');
+        sb.append(source);
+        return sb.toString();
+    }
+
+    //**** internal access ****
+
+    String name() {
+        return unitName;
+    }
+
+    Key key() {
+        return key;
+    }
+
+    List<String> unresolved() {
+        return Collections.unmodifiableList(unresolved);
+    }
+
+    DiagList diagnostics() {
+        return diagnostics;
+    }
+
+    /**
+     * @return the corralled guts
+     */
+    Wrap corralled() {
+        return null;
+    }
+
+    Collection<String> declareReferences() {
+        return null;
+    }
+
+    Collection<String> bodyReferences() {
+        return null;
+    }
+
+    String importLine(JShell state) {
+        return "";
+    }
+
+    void setId(String id) {
+        this.id = id;
+    }
+
+    final void setSequenceNumber(int seq) {
+        this.seq = seq;
+        this.className = REPL_CLASS_PREFIX + key().index() + asLetters(seq);
+    }
+
+    void setOuterWrap(OuterWrap outer) {
+        this.outer = outer;
+    }
+
+    void setCompilationStatus(Status status, List<String> unresolved, DiagList diagnostics) {
+        this.status = status;
+        this.unresolved = unresolved;
+        this.diagnostics = diagnostics;
+    }
+
+    void setDiagnostics(DiagList diagnostics) {
+        this.diagnostics = diagnostics;
+    }
+
+    void setFailed(DiagList diagnostics) {
+        this.seq = -1;
+        this.outer = null;
+        this.status = Status.REJECTED;
+        this.unresolved = Collections.emptyList();
+        this.diagnostics = diagnostics;
+    }
+
+    void setDropped() {
+        this.status = Status.DROPPED;
+    }
+
+    void setOverwritten() {
+        this.status = Status.OVERWRITTEN;
+    }
+
+    Status status() {
+        return status;
+    }
+
+    String className() {
+        return className;
+    }
+
+    /**
+     * Top-level wrap
+     * @return
+     */
+    OuterWrap outerWrap() {
+        return outer;
+    }
+
+    /**
+     * Basically, class version for this Key.
+     * @return int
+     */
+    int sequenceNumber() {
+        return seq;
+    }
+
+    Wrap guts() {
+        return guts;
+    }
+
+    boolean isExecutable() {
+        return subkind.isExecutable();
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java
new file mode 100644
index 0000000..3644646
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import jdk.jshell.Snippet.Status;
+
+/**
+ * A description of a change to a Snippet. These are generated by direct changes
+ * to state with {@link JShell#eval(java.lang.String) JShell.eval(String)} or
+ * {@link JShell#drop(jdk.jshell.PersistentSnippet) JShell.drop(PersistentSnippet)},
+ * or indirectly by these same methods as
+ * dependencies change or Snippets are overwritten. For direct changes, the
+ * {@link SnippetEvent#causeSnippet()} is <code>null</code>.
+ * <p>
+ * <code>SnippetEvent</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ * @author Robert Field
+ */
+public class SnippetEvent {
+
+    SnippetEvent(Snippet snippet, Status previousStatus, Status status,
+            boolean isSignatureChange, Snippet causeSnippet,
+            String value, Exception exception) {
+        this.snippet = snippet;
+        this.previousStatus = previousStatus;
+        this.status = status;
+        this.isSignatureChange = isSignatureChange;
+        this.causeSnippet = causeSnippet;
+        this.value = value;
+        this.exception = exception;
+    }
+
+    private final Snippet snippet;
+    private final Status previousStatus;
+    private final Status status;
+    private final boolean isSignatureChange;
+    private final Snippet causeSnippet;
+    private final String value;
+    private final Exception exception;
+
+    /**
+     * The Snippet which has changed
+     * @return the return the Snippet whose <code>Status</code> has changed.
+     */
+    public Snippet snippet() {
+        return snippet;
+    }
+
+    /**
+     * The status before the transition. If this event describes a Snippet
+     * creation return {@link Snippet.Status#NONEXISTENT NONEXISTENT}.
+     * @return the previousStatus
+     */
+    public Status previousStatus() {
+        return previousStatus;
+    }
+
+    /**
+     * The after status. Note: this may be the same as the previous status (not
+     * all changes cause a <code>Status</code> change.
+     * @return the status
+     */
+    public Status status() {
+        return status;
+    }
+
+    /**
+     * Has the signature changed? Coming in or out of definition
+     * (status.isDefined) is always a signature change. An overwritten Snippet
+     * {@link jdk.jshell.Snippet.Status#OVERWRITTEN (status == OVERWRITTEN)}
+     * is always <code>false</code> as responsibility for the
+     * definition has passed to the overwriting definition.
+     * @return <code>true</code> if the signature changed.
+     */
+    public boolean isSignatureChange() {
+        return isSignatureChange;
+    }
+
+    /**
+     * Either the snippet whose change caused this update or
+     * <code>null</code>. This returns <code>null</code> if this change is the
+     * creation of a new Snippet via
+     * {@link jdk.jshell.JShell#eval(java.lang.String) eval} or it is the
+     * explicit drop of a Snippet with
+     * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop}.
+     *
+     * @return the Snippet which caused this change or <code>null</code> if
+     * directly caused by an API action.
+     */
+    public Snippet causeSnippet() {
+        return causeSnippet;
+    }
+
+    /**
+     * An instance of {@link jdk.jshell.UnresolvedReferenceException}, if an unresolved reference was
+     * encountered, or an instance of {@link jdk.jshell.EvalException} if an exception was thrown
+     * during execution, otherwise <code>null</code>.
+     * @return the exception or <code>null</code>.
+     */
+    public Exception exception() {
+        return exception;
+    }
+
+    /**
+     * The result value of successful run. The value is null if not executed
+     * or an exception was thrown.
+     * @return the value or <code>null</code>.
+     */
+    public String value() {
+        return value;
+    }
+
+    /**
+     * Return a string representation of the event
+     * @return a descriptive representation of the SnippetEvent
+     */
+    @Override
+    public String toString() {
+        return "SnippetEvent(snippet=" + snippet +
+                ",previousStatus=" + previousStatus +
+                ",status=" + status +
+                ",isSignatureChange=" + isSignatureChange +
+                ",causeSnippet" + causeSnippet +
+                (value == null? "" : "value=" + value) +
+                (exception == null? "" : "exception=" + exception) +
+                ")";
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java
new file mode 100644
index 0000000..149a90e
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetMaps.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toList;
+import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_DEP;
+
+/**
+ * Maintain relationships between the significant entities: Snippets,
+ * internal snippet index, Keys, etc.
+ * @author Robert Field
+ */
+final class SnippetMaps {
+
+    private String packageName;
+    private final List<Snippet> keyIndexToSnippet = new ArrayList<>();
+    private final Set<Snippet> snippets = new LinkedHashSet<>();
+    private final Map<String, Set<Integer>> dependencies = new HashMap<>();
+    private final JShell state;
+
+    SnippetMaps(JShell proc) {
+        this.state = proc;
+    }
+
+    void installSnippet(Snippet sn) {
+        if (sn != null && snippets.add(sn)) {
+            if (sn.key() != null) {
+                sn.setId((state.idGenerator != null)
+                        ? state.idGenerator.apply(sn, sn.key().index())
+                        : "" + sn.key().index());
+                setSnippet(sn.key().index(), sn);
+            }
+        }
+    }
+
+    private void setSnippet(int ki, Snippet snip) {
+        while (ki >= keyIndexToSnippet.size()) {
+            keyIndexToSnippet.add(null);
+        }
+        keyIndexToSnippet.set(ki, snip);
+    }
+
+    Snippet getSnippet(Key key) {
+        return getSnippet(key.index());
+    }
+
+    Snippet getSnippet(int ki) {
+        if (ki >= keyIndexToSnippet.size()) {
+            return null;
+        }
+        return keyIndexToSnippet.get(ki);
+    }
+
+    List<Snippet> snippetList() {
+        return new ArrayList<>(snippets);
+    }
+
+    void setPackageName(String n) {
+        packageName = n;
+    }
+
+    String packageName() {
+        return packageName;
+    }
+
+    String classFullName(Snippet sn) {
+        return packageName + "." + sn.className();
+    }
+
+    String packageAndImportsExcept(Set<Key> except, Collection<Snippet> plus) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("package ").append(packageName()).append(";\n");
+        for (Snippet si : keyIndexToSnippet) {
+            if (si != null && si.status().isDefined && (except == null || !except.contains(si.key()))) {
+                sb.append(si.importLine(state));
+            }
+        }
+        if (plus != null) {
+            plus.stream()
+                    .forEach(psi -> sb.append(psi.importLine(state)));
+        }
+        return sb.toString();
+    }
+
+    List<Snippet> getDependents(Snippet snip) {
+        if (!snip.kind().isPersistent) {
+            return Collections.emptyList();
+        }
+        Set<Integer> depset;
+        if (snip.unitName.equals("*")) {
+            // star import
+            depset = new HashSet<>();
+            for (Set<Integer> as : dependencies.values()) {
+                depset.addAll(as);
+            }
+        } else {
+            depset = dependencies.get(snip.name());
+        }
+        if (depset == null) {
+            return Collections.emptyList();
+        }
+        List<Snippet> deps = new ArrayList<>();
+        for (Integer dss : depset) {
+            Snippet dep = getSnippet(dss);
+            if (dep != null) {
+                deps.add(dep);
+                state.debug(DBG_DEP, "Found dependency %s -> %s\n", snip.name(), dep.name());
+            }
+        }
+        return deps;
+    }
+
+    void mapDependencies(Snippet snip) {
+        addDependencies(snip.declareReferences(), snip);
+        addDependencies(snip.bodyReferences(),    snip);
+    }
+
+    private void addDependencies(Collection<String> refs, Snippet snip) {
+        if (refs == null) return;
+        for (String ref : refs) {
+            dependencies.computeIfAbsent(ref, k -> new HashSet<>())
+                        .add(snip.key().index());
+            state.debug(DBG_DEP, "Added dependency %s -> %s\n", ref, snip.name());
+        }
+    }
+
+    String fullClassNameAndPackageToClass(String full, String pkg) {
+        Matcher mat = prefixPattern.matcher(full);
+        if (mat.lookingAt()) {
+            return full.substring(mat.end());
+        }
+        state.debug(DBG_DEP, "SM %s %s\n", full, pkg);
+        List<String> klasses = importSnippets()
+                               .filter(isi -> !isi.isStar)
+                               .map(isi -> isi.fullname)
+                               .collect(toList());
+        for (String k : klasses) {
+            if (k.equals(full)) {
+                return full.substring(full.lastIndexOf(".")+1, full.length());
+            }
+        }
+        List<String> pkgs = importSnippets()
+                               .filter(isi -> isi.isStar)
+                               .map(isi -> isi.fullname.substring(0, isi.fullname.lastIndexOf(".")))
+                               .collect(toList());
+        pkgs.add(0, "java.lang");
+        for (String ipkg : pkgs) {
+            if (!ipkg.isEmpty() && ipkg.equals(pkg)) {
+                return full.substring(pkg.length() + 1);
+            }
+        }
+        return full;
+    }
+
+    /**
+     * Compute the set of imports to prepend to a snippet
+     * @return a stream of the import needed
+     */
+    private Stream<ImportSnippet> importSnippets() {
+        return state.keyMap.importKeys()
+                .map(key -> (ImportSnippet)getSnippet(key))
+                .filter(sn -> state.status(sn).isDefined);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java
new file mode 100644
index 0000000..f9a31f1
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.List;
+
+/**
+ * Provides analysis utilities for source code input.
+ * Optional functionality that provides for a richer interactive experience.
+ * Includes completion analysis:
+ * Is the input a complete snippet of code?
+ * Do I need to prompt for more input?
+ * Would adding a semicolon make it complete?
+ * Is there more than one snippet?
+ * etc.
+ * Also includes completion suggestions, as might be used in tab-completion.
+ *
+ */
+public abstract class SourceCodeAnalysis {
+
+    /**
+     * Given an input string, find the first snippet of code (one statement,
+     * definition, import, or expression) and evaluate if it is complete.
+     * @param input the input source string
+     * @return a CompletionInfo instance with location and completeness info
+     */
+    public abstract CompletionInfo analyzeCompletion(String input);
+
+    /**
+     * Compute possible follow-ups for the given input.
+     * Uses information from the current <code>JShell</code> state, including
+     * type information, to filter the suggestions.
+     * @param input the user input, so far
+     * @param cursor the current position of the cursors in the given {@code input} text
+     * @param anchor outgoing parameter - when an option will be completed, the text between
+     *               the anchor and cursor will be deleted and replaced with the given option
+     * @return list of candidate continuations of the given input.
+     */
+    public abstract List<Suggestion> completionSuggestions(String input, int cursor, int[] anchor);
+
+    /**
+     * Compute a description/help string for the given user's input.
+     * @param input the snippet the user wrote so far
+     * @param cursor the current position of the cursors in the given {@code input} text
+     * @return description/help string for the given user's input
+     */
+    public abstract String documentation(String input, int cursor);
+
+    /**
+     * Internal only constructor
+     */
+    SourceCodeAnalysis() {}
+
+    /**
+     * The result of <code>analyzeCompletion(String input)</code>.
+     * Describes the completeness and position of the first snippet in the given input.
+     */
+    public static class CompletionInfo {
+
+        public CompletionInfo(Completeness completeness, int unitEndPos, String source, String remaining) {
+            this.completeness = completeness;
+            this.unitEndPos = unitEndPos;
+            this.source = source;
+            this.remaining = remaining;
+        }
+
+        /**
+         * The analyzed completeness of the input.
+         */
+        public final Completeness completeness;
+
+        /**
+         * The end of the first unit of source.
+         */
+        public final int unitEndPos;
+
+        /**
+         * Source code for the first unit of code input.  For example, first
+         * statement, or first method declaration.  Trailing semicolons will
+         * be added, as needed
+         */
+        public final String source;
+
+        /**
+         * Input remaining after the source
+         */
+        public final String remaining;
+    }
+
+    /**
+     * Describes the completeness of the given input.
+     */
+    public enum Completeness {
+        /**
+         * The input is a complete source snippet (declaration or statement) as is.
+         */
+        COMPLETE(true),
+
+        /**
+         * With this addition of a semicolon the input is a complete source snippet.
+         * This will only be returned when the end of input is encountered.
+         */
+        COMPLETE_WITH_SEMI(true),
+
+        /**
+         * There must be further source beyond the given input in order for it
+         * to be complete.  A semicolon would not complete it.
+         * This will only be returned when the end of input is encountered.
+         */
+        DEFINITELY_INCOMPLETE(false),
+
+        /**
+         * A statement with a trailing (non-terminated) empty statement.
+         * Though technically it would be a complete statement
+         * with the addition of a semicolon, it is rare
+         * that that assumption is the desired behavior.
+         * The input is considered incomplete.  Comments and white-space are
+         * still considered empty.
+         */
+        CONSIDERED_INCOMPLETE(false),
+
+
+        /**
+         * An empty input.
+         * The input is considered incomplete.  Comments and white-space are
+         * still considered empty.
+         */
+        EMPTY(false),
+
+        /**
+         * The completeness of the input could not be determined because it
+         * contains errors. Error detection is not a goal of completeness
+         * analysis, however errors interfered with determining its completeness.
+         * The input is considered complete because evaluating is the best
+         * mechanism to get error information.
+         */
+        UNKNOWN(true);
+
+        /**
+         * Is the first snippet of source complete. For example, "x=" is not
+         * complete, but "x=2" is complete, even though a subsequent line could
+         * make it "x=2+2". Already erroneous code is marked complete.
+         */
+        public final boolean isComplete;
+
+        Completeness(boolean isComplete) {
+            this.isComplete = isComplete;
+        }
+    }
+
+    /**
+     * A candidate for continuation of the given user's input.
+     */
+    public static class Suggestion {
+
+        /**
+         * Create a {@code Suggestion} instance.
+         * @param continuation a candidate continuation of the user's input
+         * @param isSmart is the candidate "smart"
+         */
+        public Suggestion(String continuation, boolean isSmart) {
+            this.continuation = continuation;
+            this.isSmart = isSmart;
+        }
+
+        /**
+         * The candidate continuation of the given user's input.
+         */
+        public final String continuation;
+
+        /**
+         * Is it an input continuation that matches the target type and is thus more
+         * likely to be the desired continuation. A smart continuation
+         * is preferred.
+         */
+        public final boolean isSmart;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java
new file mode 100644
index 0000000..b55b235
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import jdk.jshell.SourceCodeAnalysis.Completeness;
+import com.sun.source.tree.AssignmentTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ErroneousTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.ImportTree;
+import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.MethodInvocationTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.Scope;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.Tree.Kind;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacScope;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.util.Pair;
+import jdk.jshell.CompletenessAnalyzer.CaInfo;
+import jdk.jshell.TaskFactory.AnalyzeTask;
+import jdk.jshell.TaskFactory.ParseTask;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Predicate;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_COMPA;
+
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.QualifiedNameable;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
+
+/**
+ * The concrete implementation of SourceCodeAnalysis.
+ * @author Robert Field
+ */
+class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
+    private final JShell proc;
+    private final CompletenessAnalyzer ca;
+
+    SourceCodeAnalysisImpl(JShell proc) {
+        this.proc = proc;
+        this.ca = new CompletenessAnalyzer(proc);
+    }
+
+    @Override
+    public CompletionInfo analyzeCompletion(String srcInput) {
+        MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
+        String cleared = mcm.cleared();
+        String trimmedInput = Util.trimEnd(cleared);
+        if (trimmedInput.isEmpty()) {
+            // Just comment or empty
+            return new CompletionInfo(Completeness.EMPTY, srcInput.length(), srcInput, "");
+        }
+        CaInfo info = ca.scan(trimmedInput);
+        Completeness status = info.status;
+        int unitEndPos = info.unitEndPos;
+        if (unitEndPos > srcInput.length()) {
+            unitEndPos = srcInput.length();
+        }
+        int nonCommentNonWhiteLength = trimmedInput.length();
+        String src = srcInput.substring(0, unitEndPos);
+        switch (status) {
+            case COMPLETE:
+                if (unitEndPos == nonCommentNonWhiteLength) {
+                    // The unit is the whole non-coment/white input plus semicolon
+                    String compileSource = src
+                            + mcm.mask().substring(nonCommentNonWhiteLength);
+                    proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
+                    proc.debug(DBG_COMPA, "   nothing remains.\n");
+                    return new CompletionInfo(status, unitEndPos, compileSource, "");
+                } else {
+                    String remain = srcInput.substring(unitEndPos);
+                    proc.debug(DBG_COMPA, "Complete: %s\n", src);
+                    proc.debug(DBG_COMPA, "          remaining: %s\n", remain);
+                    return new CompletionInfo(status, unitEndPos, src, remain);
+                }
+            case COMPLETE_WITH_SEMI:
+                // The unit is the whole non-coment/white input plus semicolon
+                String compileSource = src
+                        + ";"
+                        + mcm.mask().substring(nonCommentNonWhiteLength);
+                proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
+                proc.debug(DBG_COMPA, "   nothing remains.\n");
+                return new CompletionInfo(status, unitEndPos, compileSource, "");
+            case DEFINITELY_INCOMPLETE:
+                proc.debug(DBG_COMPA, "Incomplete: %s\n", srcInput);
+                return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
+            case CONSIDERED_INCOMPLETE:
+                proc.debug(DBG_COMPA, "Considered incomplete: %s\n", srcInput);
+                return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
+            case EMPTY:
+                proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
+                return new CompletionInfo(status, unitEndPos, srcInput, "");
+            case UNKNOWN:
+                proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
+                return new CompletionInfo(status, unitEndPos, srcInput, "");
+        }
+        throw new InternalError();
+    }
+
+    private OuterWrap wrapInClass(Wrap guts) {
+        String imports = proc.maps.packageAndImportsExcept(null, null);
+        return OuterWrap.wrapInClass(proc.maps.packageName(), REPL_DOESNOTMATTER_CLASS_NAME, imports, "", guts);
+    }
+
+    private Tree.Kind guessKind(String code) {
+        ParseTask pt = proc.taskFactory.new ParseTask(code);
+        List<? extends Tree> units = pt.units();
+        if (units.isEmpty()) {
+            return Tree.Kind.BLOCK;
+        }
+        Tree unitTree = units.get(0);
+        proc.debug(DBG_COMPA, "Kind: %s -- %s\n", unitTree.getKind(), unitTree);
+        return unitTree.getKind();
+    }
+
+    //TODO: would be better handled through a lexer:
+    private final Pattern JAVA_IDENTIFIER = Pattern.compile("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*");
+
+    @Override
+    public List<Suggestion> completionSuggestions(String code, int cursor, int[] anchor) {
+        code = code.substring(0, cursor);
+        Matcher m = JAVA_IDENTIFIER.matcher(code);
+        String identifier = "";
+        while (m.find()) {
+            if (m.end() == code.length()) {
+                cursor = m.start();
+                code = code.substring(0, cursor);
+                identifier = m.group();
+            }
+        }
+        code = code.substring(0, cursor);
+        if (code.trim().isEmpty()) { //TODO: comment handling
+            code += ";";
+        }
+        OuterWrap codeWrap;
+        switch (guessKind(code)) {
+            case IMPORT:
+                codeWrap = OuterWrap.wrapImport(null, Wrap.importWrap(code + "any.any"));
+                break;
+            case METHOD:
+                codeWrap = wrapInClass(Wrap.classMemberWrap(code));
+                break;
+            default:
+                codeWrap = wrapInClass(Wrap.methodWrap(code));
+                break;
+        }
+        String requiredPrefix = identifier;
+        return computeSuggestions(codeWrap, cursor, anchor).stream()
+                .filter(s -> s.continuation.startsWith(requiredPrefix) && !s.continuation.equals(REPL_DOESNOTMATTER_CLASS_NAME))
+                .sorted(Comparator.comparing(s -> s.continuation))
+                .collect(collectingAndThen(toList(), Collections::unmodifiableList));
+    }
+
+    private List<Suggestion> computeSuggestions(OuterWrap code, int cursor, int[] anchor) {
+        AnalyzeTask at = proc.taskFactory.new AnalyzeTask(code);
+        SourcePositions sp = at.trees().getSourcePositions();
+        CompilationUnitTree topLevel = at.cuTree();
+        List<Suggestion> result = new ArrayList<>();
+        TreePath tp = pathFor(topLevel, sp, code.snippetIndexToWrapIndex(cursor));
+        if (tp != null) {
+            Scope scope = at.trees().getScope(tp);
+            Predicate<Element> accessibility = createAccessibilityFilter(at, tp);
+            Predicate<Element> smartTypeFilter;
+            Predicate<Element> smartFilter;
+            Iterable<TypeMirror> targetTypes = findTargetType(at, tp);
+            if (targetTypes != null) {
+                smartTypeFilter = el -> {
+                    TypeMirror resultOf = resultTypeOf(el);
+                    return Util.stream(targetTypes)
+                            .anyMatch(targetType -> at.getTypes().isAssignable(resultOf, targetType));
+                };
+
+                smartFilter = IS_CLASS.negate()
+                                      .and(IS_INTERFACE.negate())
+                                      .and(IS_PACKAGE.negate())
+                                      .and(smartTypeFilter);
+            } else {
+                smartFilter = TRUE;
+                smartTypeFilter = TRUE;
+            }
+            switch (tp.getLeaf().getKind()) {
+                case MEMBER_SELECT: {
+                    MemberSelectTree mst = (MemberSelectTree)tp.getLeaf();
+                    if (mst.getIdentifier().contentEquals("*"))
+                        break;
+                    TreePath exprPath = new TreePath(tp, mst.getExpression());
+                    TypeMirror site = at.trees().getTypeMirror(exprPath);
+                    boolean staticOnly = isStaticContext(at, exprPath);
+                    ImportTree it = findImport(tp);
+                    boolean isImport = it != null;
+
+                    List<? extends Element> members = membersOf(at, site, staticOnly && !isImport);
+                    Predicate<Element> filter = accessibility;
+                    Function<Boolean, String> paren = DEFAULT_PAREN;
+
+                    if (isNewClass(tp)) { // new xxx.|
+                        Predicate<Element> constructorFilter = accessibility.and(IS_CONSTRUCTOR)
+                            .and(el -> {
+                                if (el.getEnclosingElement().getEnclosingElement().getKind() == ElementKind.CLASS) {
+                                    return el.getEnclosingElement().getModifiers().contains(Modifier.STATIC);
+                                }
+                                return true;
+                            });
+                        addElements(membersOf(at, members), constructorFilter, smartFilter, result);
+
+                        filter = filter.and(IS_PACKAGE);
+                    } else if (isThrowsClause(tp)) {
+                        staticOnly = true;
+                        filter = filter.and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
+                        smartFilter = IS_PACKAGE.negate().and(smartTypeFilter);
+                    } else if (isImport) {
+                        paren = NO_PAREN;
+                        if (!it.isStatic()) {
+                            filter = filter.and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
+                        }
+                    } else {
+                        filter = filter.and(IS_CONSTRUCTOR.negate());
+                    }
+
+                    filter = filter.and(staticOnly ? STATIC_ONLY : INSTANCE_ONLY);
+
+                    addElements(members, filter, smartFilter, paren, result);
+                    break;
+                }
+                case IDENTIFIER:
+                    if (isNewClass(tp)) {
+                        Function<Element, Iterable<? extends Element>> listEnclosed =
+                                el -> el.getKind() == ElementKind.PACKAGE ? Collections.singletonList(el)
+                                                                          : el.getEnclosedElements();
+                        Predicate<Element> filter = accessibility.and(IS_CONSTRUCTOR.or(IS_PACKAGE));
+                        NewClassTree newClassTree = (NewClassTree)tp.getParentPath().getLeaf();
+                        ExpressionTree enclosingExpression = newClassTree.getEnclosingExpression();
+                        if (enclosingExpression != null) { // expr.new IDENT|
+                            TypeMirror site = at.trees().getTypeMirror(new TreePath(tp, enclosingExpression));
+                            filter = filter.and(el -> el.getEnclosingElement().getKind() == ElementKind.CLASS && !el.getEnclosingElement().getModifiers().contains(Modifier.STATIC));
+                            addElements(membersOf(at, membersOf(at, site, false)), filter, smartFilter, result);
+                        } else {
+                            addScopeElements(at, scope, listEnclosed, filter, smartFilter, result);
+                        }
+                        break;
+                    }
+                    if (isThrowsClause(tp)) {
+                        Predicate<Element> accept = accessibility.and(STATIC_ONLY)
+                                .and(IS_PACKAGE.or(IS_CLASS).or(IS_INTERFACE));
+                        addScopeElements(at, scope, IDENTITY, accept, IS_PACKAGE.negate().and(smartTypeFilter), result);
+                        break;
+                    }
+                    ImportTree it = findImport(tp);
+                    if (it != null) {
+                        addElements(membersOf(at, at.getElements().getPackageElement("").asType(), false), it.isStatic() ? STATIC_ONLY.and(accessibility) : accessibility, smartFilter, result);
+                    }
+                    break;
+                case ERRONEOUS:
+                case EMPTY_STATEMENT: {
+                    boolean staticOnly = ReplResolve.isStatic(((JavacScope)scope).getEnv());
+                    Predicate<Element> accept = accessibility.and(staticOnly ? STATIC_ONLY : TRUE);
+                    addScopeElements(at, scope, IDENTITY, accept, smartFilter, result);
+
+                    Tree parent = tp.getParentPath().getLeaf();
+                    switch (parent.getKind()) {
+                        case VARIABLE:
+                            accept = ((VariableTree)parent).getType() == tp.getLeaf() ?
+                                    IS_VOID.negate() :
+                                    TRUE;
+                            break;
+                        case PARAMETERIZED_TYPE: // TODO: JEP 218: Generics over Primitive Types
+                        case TYPE_PARAMETER:
+                        case CLASS:
+                        case INTERFACE:
+                        case ENUM:
+                            accept = FALSE;
+                            break;
+                        default:
+                            accept = TRUE;
+                            break;
+                    }
+                    addElements(primitivesOrVoid(at), accept, smartFilter, result);
+                    break;
+                }
+            }
+        }
+        anchor[0] = cursor;
+        return result;
+    }
+
+    private boolean isStaticContext(AnalyzeTask at, TreePath path) {
+        switch (path.getLeaf().getKind()) {
+            case ARRAY_TYPE:
+            case PRIMITIVE_TYPE:
+                return true;
+            default:
+                Element selectEl = at.trees().getElement(path);
+                return selectEl != null && (selectEl.getKind().isClass() || selectEl.getKind().isInterface() || selectEl.getKind() == ElementKind.TYPE_PARAMETER) && selectEl.asType().getKind() != TypeKind.ERROR;
+        }
+    }
+
+    private TreePath pathFor(CompilationUnitTree topLevel, SourcePositions sp, int pos) {
+        TreePath[] deepest = new TreePath[1];
+
+        new TreePathScanner<Void, Void>() {
+            @Override @DefinedBy(Api.COMPILER_TREE)
+            public Void scan(Tree tree, Void p) {
+                if (tree == null)
+                    return null;
+
+                long start = sp.getStartPosition(topLevel, tree);
+                long end = sp.getEndPosition(topLevel, tree);
+
+                if (start <= pos && pos <= end) {
+                    deepest[0] = new TreePath(getCurrentPath(), tree);
+                    return super.scan(tree, p);
+                }
+
+                return null;
+            }
+            @Override @DefinedBy(Api.COMPILER_TREE)
+            public Void visitErroneous(ErroneousTree node, Void p) {
+                return scan(node.getErrorTrees(), null);
+            }
+        }.scan(topLevel, null);
+
+        return deepest[0];
+    }
+
+    private boolean isNewClass(TreePath tp) {
+        return tp.getParentPath() != null &&
+               tp.getParentPath().getLeaf().getKind() == Kind.NEW_CLASS &&
+               ((NewClassTree) tp.getParentPath().getLeaf()).getIdentifier() == tp.getLeaf();
+    }
+
+    private boolean isThrowsClause(TreePath tp) {
+        Tree parent = tp.getParentPath().getLeaf();
+        return parent.getKind() == Kind.METHOD &&
+                ((MethodTree)parent).getThrows().contains(tp.getLeaf());
+    }
+
+    private ImportTree findImport(TreePath tp) {
+        while (tp != null && tp.getLeaf().getKind() != Kind.IMPORT) {
+            tp = tp.getParentPath();
+        }
+        return tp != null ? (ImportTree)tp.getLeaf() : null;
+    }
+
+    private Predicate<Element> createAccessibilityFilter(AnalyzeTask at, TreePath tp) {
+        Scope scope = at.trees().getScope(tp);
+        return el -> {
+            switch (el.getKind()) {
+                case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
+                    return at.trees().isAccessible(scope, (TypeElement) el);
+                case PACKAGE:
+                case EXCEPTION_PARAMETER: case PARAMETER: case LOCAL_VARIABLE: case RESOURCE_VARIABLE:
+                    return true;
+                default:
+                    TypeMirror type = el.getEnclosingElement().asType();
+                    if (type.getKind() == TypeKind.DECLARED)
+                        return at.trees().isAccessible(scope, el, (DeclaredType) type);
+                    else
+                        return true;
+            }
+        };
+    }
+
+    private final Predicate<Element> TRUE = el -> true;
+    private final Predicate<Element> FALSE = TRUE.negate();
+    private final Predicate<Element> IS_STATIC = el -> el.getModifiers().contains(Modifier.STATIC);
+    private final Predicate<Element> IS_CONSTRUCTOR = el -> el.getKind() == ElementKind.CONSTRUCTOR;
+    private final Predicate<Element> IS_METHOD = el -> el.getKind() == ElementKind.METHOD;
+    private final Predicate<Element> IS_PACKAGE = el -> el.getKind() == ElementKind.PACKAGE;
+    private final Predicate<Element> IS_CLASS = el -> el.getKind().isClass();
+    private final Predicate<Element> IS_INTERFACE = el -> el.getKind().isInterface();
+    private final Predicate<Element> IS_VOID = el -> el.asType().getKind() == TypeKind.VOID;
+    private final Predicate<Element> STATIC_ONLY = el -> {
+        ElementKind kind = el.getKind();
+        Element encl = el.getEnclosingElement();
+        ElementKind enclKind = encl != null ? encl.getKind() : ElementKind.OTHER;
+
+        return IS_STATIC.or(IS_PACKAGE).or(IS_CLASS).or(IS_INTERFACE).test(el) || IS_PACKAGE.test(encl) ||
+                (kind == ElementKind.TYPE_PARAMETER && !enclKind.isClass() && !enclKind.isInterface());
+    };
+    private final Predicate<Element> INSTANCE_ONLY = el -> {
+        Element encl = el.getEnclosingElement();
+
+        return IS_STATIC.or(IS_CLASS).or(IS_INTERFACE).negate().test(el) ||
+                IS_PACKAGE.test(encl);
+    };
+    private final Function<Element, Iterable<? extends Element>> IDENTITY = el -> Collections.singletonList(el);
+    private final Function<Boolean, String> DEFAULT_PAREN = hasParams -> hasParams ? "(" : "()";
+    private final Function<Boolean, String> NO_PAREN = hasParams -> "";
+
+    private void addElements(Iterable<? extends Element> elements, Predicate<Element> accept, Predicate<Element> smart, List<Suggestion> result) {
+        addElements(elements, accept, smart, DEFAULT_PAREN, result);
+    }
+    private void addElements(Iterable<? extends Element> elements, Predicate<Element> accept, Predicate<Element> smart, Function<Boolean, String> paren, List<Suggestion> result) {
+        Set<String> hasParams = Util.stream(elements)
+                .filter(accept)
+                .filter(IS_CONSTRUCTOR.or(IS_METHOD))
+                .filter(c -> !((ExecutableElement)c).getParameters().isEmpty())
+                .map(this::simpleName)
+                .collect(toSet());
+
+        for (Element c : elements) {
+            if (!accept.test(c))
+                continue;
+            String simpleName = simpleName(c);
+            if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
+                simpleName += paren.apply(hasParams.contains(simpleName));
+            }
+            result.add(new Suggestion(simpleName, smart.test(c)));
+        }
+    }
+
+    private String simpleName(Element el) {
+        return el.getKind() == ElementKind.CONSTRUCTOR ? el.getEnclosingElement().getSimpleName().toString()
+                                                       : el.getSimpleName().toString();
+    }
+
+    private List<? extends Element> membersOf(AnalyzeTask at, TypeMirror site, boolean shouldGenerateDotClassItem) {
+        if (site  == null)
+            return Collections.emptyList();
+
+        switch (site.getKind()) {
+            case DECLARED: {
+                TypeElement element = (TypeElement) at.getTypes().asElement(site);
+                List<Element> result = new ArrayList<>();
+                result.addAll(at.getElements().getAllMembers(element));
+                if (shouldGenerateDotClassItem) {
+                    result.add(createDotClassSymbol(at, site));
+                }
+                result.removeIf(el -> el.getKind() == ElementKind.STATIC_INIT);
+                return result;
+            }
+            case ERROR: {
+                //try current qualified name as a package:
+                TypeElement typeElement = (TypeElement) at.getTypes().asElement(site);
+                Element enclosingElement = typeElement.getEnclosingElement();
+                String parentPackageName = enclosingElement instanceof QualifiedNameable ?
+                    ((QualifiedNameable)enclosingElement).getQualifiedName().toString() :
+                    "";
+                Set<PackageElement> packages = listPackages(at, parentPackageName);
+                return packages.stream()
+                               .filter(p -> p.getQualifiedName().equals(typeElement.getQualifiedName()))
+                               .findAny()
+                               .map(p -> membersOf(at, p.asType(), false))
+                               .orElse(Collections.emptyList());
+            }
+            case PACKAGE: {
+                String packageName = site.toString()/*XXX*/;
+                List<Element> result = new ArrayList<>();
+                result.addAll(getEnclosedElements(at.getElements().getPackageElement(packageName)));
+                result.addAll(listPackages(at, packageName));
+                return result;
+            }
+            case BOOLEAN: case BYTE: case SHORT: case CHAR:
+            case INT: case FLOAT: case LONG: case DOUBLE:
+            case VOID: {
+                return shouldGenerateDotClassItem ?
+                    Collections.singletonList(createDotClassSymbol(at, site)) :
+                    Collections.emptyList();
+            }
+            case ARRAY: {
+                List<Element> result = new ArrayList<>();
+                result.add(createArrayLengthSymbol(at, site));
+                if (shouldGenerateDotClassItem)
+                    result.add(createDotClassSymbol(at, site));
+                return result;
+            }
+            default:
+                return Collections.emptyList();
+        }
+    }
+
+    private List<? extends Element> membersOf(AnalyzeTask at, List<? extends Element> elements) {
+        return elements.stream()
+                .flatMap(e -> membersOf(at, e.asType(), true).stream())
+                .collect(toList());
+    }
+
+    private List<? extends Element> getEnclosedElements(PackageElement packageEl) {
+        if (packageEl == null) {
+            return Collections.emptyList();
+        }
+        //workaround for: JDK-8024687
+        while (true) {
+            try {
+                return packageEl.getEnclosedElements()
+                                .stream()
+                                .filter(el -> el.asType() != null)
+                                .filter(el -> el.asType().getKind() != TypeKind.ERROR)
+                                .collect(toList());
+            } catch (CompletionFailure cf) {
+                //ignore...
+            }
+        }
+    }
+
+    private List<? extends Element> primitivesOrVoid(AnalyzeTask at) {
+        Types types = at.getTypes();
+        return Stream.of(
+                TypeKind.BOOLEAN, TypeKind.BYTE, TypeKind.CHAR,
+                TypeKind.DOUBLE, TypeKind.FLOAT, TypeKind.INT,
+                TypeKind.LONG, TypeKind.SHORT, TypeKind.VOID)
+                .map(tk -> (Type)(tk == TypeKind.VOID ? types.getNoType(tk) : types.getPrimitiveType(tk)))
+                .map(Type::asElement)
+                .collect(toList());
+    }
+
+    private Set<PackageElement> listPackages(AnalyzeTask at, String enclosingPackage) {
+        Set<PackageElement> packs = new HashSet<>();
+        listPackages(at, StandardLocation.PLATFORM_CLASS_PATH, enclosingPackage, packs);
+        listPackages(at, StandardLocation.CLASS_PATH, enclosingPackage, packs);
+        listPackages(at, StandardLocation.SOURCE_PATH, enclosingPackage, packs);
+        return packs;
+    }
+
+    private void listPackages(AnalyzeTask at, Location loc, String currentPackage, Set<PackageElement> packs) {
+        try {
+            MemoryFileManager fm = proc.taskFactory.fileManager();
+            for (JavaFileObject file : fm.list(loc, currentPackage, fileKinds, true)) {
+                String binaryName = fm.inferBinaryName(loc, file);
+                if (!currentPackage.isEmpty() && !binaryName.startsWith(currentPackage + "."))
+                    continue;
+                int nextDot = binaryName.indexOf('.', !currentPackage.isEmpty() ? currentPackage.length() + 1 : 0);
+                if (nextDot == (-1))
+                    continue;
+                Elements elements = at.getElements();
+                PackageElement pack =
+                        elements.getPackageElement(binaryName.substring(0, nextDot));
+                if (pack == null) {
+                    //if no types in the package have ever been seen, the package will be unknown
+                    //try to load a type, and then try to recognize the package again:
+                    elements.getTypeElement(binaryName);
+                    pack = elements.getPackageElement(binaryName.substring(0, nextDot));
+                }
+                if (pack != null)
+                    packs.add(pack);
+            }
+        } catch (IOException ex) {
+            //TODO: should log?
+        }
+    }
+    //where:
+        private final Set<JavaFileObject.Kind> fileKinds = EnumSet.of(JavaFileObject.Kind.CLASS);
+
+    private Element createArrayLengthSymbol(AnalyzeTask at, TypeMirror site) {
+        Name length = Names.instance(at.getContext()).length;
+        Type intType = Symtab.instance(at.getContext()).intType;
+
+        return new VarSymbol(Flags.PUBLIC | Flags.FINAL, length, intType, ((Type) site).tsym);
+    }
+
+    private Element createDotClassSymbol(AnalyzeTask at, TypeMirror site) {
+        Name _class = Names.instance(at.getContext())._class;
+        Type classType = Symtab.instance(at.getContext()).classType;
+        Type erasedSite = (Type)at.getTypes().erasure(site);
+        classType = new ClassType(classType.getEnclosingType(), com.sun.tools.javac.util.List.of(erasedSite), classType.asElement());
+
+        return new VarSymbol(Flags.PUBLIC | Flags.STATIC | Flags.FINAL, _class, classType, erasedSite.tsym);
+    }
+
+    private Iterable<? extends Element> scopeContent(AnalyzeTask at, Scope scope, Function<Element, Iterable<? extends Element>> elementConvertor) {
+        Iterable<Scope> scopeIterable = () -> new Iterator<Scope>() {
+            private Scope currentScope = scope;
+            @Override
+            public boolean hasNext() {
+                return currentScope != null;
+            }
+            @Override
+            public Scope next() {
+                if (!hasNext())
+                    throw new NoSuchElementException();
+                try {
+                    return currentScope;
+                } finally {
+                    currentScope = currentScope.getEnclosingScope();
+                }
+            }
+        };
+        @SuppressWarnings("unchecked")
+        List<Element> result = Util.stream(scopeIterable)
+                             .flatMap(s -> Util.stream((Iterable<Element>)s.getLocalElements()))
+                             .flatMap(el -> Util.stream((Iterable<Element>)elementConvertor.apply(el)))
+                             .collect(toCollection(ArrayList :: new));
+        result.addAll(listPackages(at, ""));
+        return result;
+    }
+
+    @SuppressWarnings("fallthrough")
+    private Iterable<TypeMirror> findTargetType(AnalyzeTask at, TreePath forPath) {
+        if (forPath.getParentPath() == null)
+            return null;
+
+        Tree current = forPath.getLeaf();
+
+        switch (forPath.getParentPath().getLeaf().getKind()) {
+            case ASSIGNMENT: {
+                AssignmentTree tree = (AssignmentTree) forPath.getParentPath().getLeaf();
+                if (tree.getExpression() == current)
+                    return Collections.singletonList(at.trees().getTypeMirror(new TreePath(forPath.getParentPath(), tree.getVariable())));
+                break;
+            }
+            case VARIABLE: {
+                VariableTree tree = (VariableTree) forPath.getParentPath().getLeaf();
+                if (tree.getInitializer()== current)
+                    return Collections.singletonList(at.trees().getTypeMirror(forPath.getParentPath()));
+                break;
+            }
+            case ERRONEOUS:
+                return findTargetType(at, forPath.getParentPath());
+            case NEW_CLASS: {
+                NewClassTree nct = (NewClassTree) forPath.getParentPath().getLeaf();
+                List<TypeMirror> actuals = computeActualInvocationTypes(at, nct.getArguments(), forPath);
+
+                if (actuals != null) {
+                    Iterable<Pair<ExecutableElement, ExecutableType>> candidateConstructors = newClassCandidates(at, forPath.getParentPath());
+
+                    return computeSmartTypesForExecutableType(at, candidateConstructors, actuals);
+                } else {
+                    return findTargetType(at, forPath.getParentPath());
+                }
+            }
+            case METHOD:
+                if (!isThrowsClause(forPath)) {
+                    break;
+                }
+                // fall through
+            case THROW:
+                return Collections.singletonList(at.getElements().getTypeElement("java.lang.Throwable").asType());
+            case METHOD_INVOCATION: {
+                MethodInvocationTree mit = (MethodInvocationTree) forPath.getParentPath().getLeaf();
+                List<TypeMirror> actuals = computeActualInvocationTypes(at, mit.getArguments(), forPath);
+
+                if (actuals == null)
+                    return null;
+
+                Iterable<Pair<ExecutableElement, ExecutableType>> candidateMethods = methodCandidates(at, forPath.getParentPath());
+
+                return computeSmartTypesForExecutableType(at, candidateMethods, actuals);
+            }
+        }
+
+        return null;
+    }
+
+    private List<TypeMirror> computeActualInvocationTypes(AnalyzeTask at, List<? extends ExpressionTree> arguments, TreePath currentArgument) {
+        if (currentArgument == null)
+            return null;
+
+        int paramIndex = arguments.indexOf(currentArgument.getLeaf());
+
+        if (paramIndex == (-1))
+            return null;
+
+        List<TypeMirror> actuals = new ArrayList<>();
+
+        for (ExpressionTree arg : arguments.subList(0, paramIndex)) {
+            actuals.add(at.trees().getTypeMirror(new TreePath(currentArgument.getParentPath(), arg)));
+        }
+
+        return actuals;
+    }
+
+    private List<Pair<ExecutableElement, ExecutableType>> filterExecutableTypesByArguments(AnalyzeTask at, Iterable<Pair<ExecutableElement, ExecutableType>> candidateMethods, List<TypeMirror> precedingActualTypes) {
+        List<Pair<ExecutableElement, ExecutableType>> candidate = new ArrayList<>();
+        int paramIndex = precedingActualTypes.size();
+
+        OUTER:
+        for (Pair<ExecutableElement, ExecutableType> method : candidateMethods) {
+            boolean varargInvocation = paramIndex >= method.snd.getParameterTypes().size();
+
+            for (int i = 0; i < paramIndex; i++) {
+                TypeMirror actual = precedingActualTypes.get(i);
+
+                if (this.parameterType(method.fst, method.snd, i, !varargInvocation)
+                        .noneMatch(formal -> at.getTypes().isAssignable(actual, formal))) {
+                    continue OUTER;
+                }
+            }
+            candidate.add(method);
+        }
+
+        return candidate;
+    }
+
+    private Stream<TypeMirror> parameterType(ExecutableElement method, ExecutableType methodType, int paramIndex, boolean allowVarArgsArray) {
+        int paramCount = methodType.getParameterTypes().size();
+        if (paramIndex >= paramCount && !method.isVarArgs())
+            return Stream.empty();
+        if (paramIndex < paramCount - 1 || !method.isVarArgs())
+            return Stream.of(methodType.getParameterTypes().get(paramIndex));
+        TypeMirror varargType = methodType.getParameterTypes().get(paramCount - 1);
+        TypeMirror elemenType = ((ArrayType) varargType).getComponentType();
+        if (paramIndex >= paramCount || !allowVarArgsArray)
+            return Stream.of(elemenType);
+        return Stream.of(varargType, elemenType);
+    }
+
+    private List<TypeMirror> computeSmartTypesForExecutableType(AnalyzeTask at, Iterable<Pair<ExecutableElement, ExecutableType>> candidateMethods, List<TypeMirror> precedingActualTypes) {
+        List<TypeMirror> candidate = new ArrayList<>();
+        int paramIndex = precedingActualTypes.size();
+
+        this.filterExecutableTypesByArguments(at, candidateMethods, precedingActualTypes)
+            .stream()
+            .flatMap(method -> parameterType(method.fst, method.snd, paramIndex, true))
+            .forEach(candidate::add);
+
+        return candidate;
+    }
+
+
+    private TypeMirror resultTypeOf(Element el) {
+        //TODO: should reflect the type of site!
+        switch (el.getKind()) {
+            case METHOD:
+                return ((ExecutableElement) el).getReturnType();
+            case CONSTRUCTOR:
+            case INSTANCE_INIT: case STATIC_INIT: //TODO: should be filtered out
+                return el.getEnclosingElement().asType();
+            default:
+                return el.asType();
+        }
+    }
+
+    private void addScopeElements(AnalyzeTask at, Scope scope, Function<Element, Iterable<? extends Element>> elementConvertor, Predicate<Element> filter, Predicate<Element> smartFilter, List<Suggestion> result) {
+        addElements(scopeContent(at, scope, elementConvertor), filter, smartFilter, result);
+    }
+
+    private Iterable<Pair<ExecutableElement, ExecutableType>> methodCandidates(AnalyzeTask at, TreePath invocation) {
+        MethodInvocationTree mit = (MethodInvocationTree) invocation.getLeaf();
+        ExpressionTree select = mit.getMethodSelect();
+        List<Pair<ExecutableElement, ExecutableType>> result = new ArrayList<>();
+        Predicate<Element> accessibility = createAccessibilityFilter(at, invocation);
+
+        switch (select.getKind()) {
+            case MEMBER_SELECT:
+                MemberSelectTree mst = (MemberSelectTree) select;
+                TreePath tp = new TreePath(new TreePath(invocation, select), mst.getExpression());
+                TypeMirror site = at.trees().getTypeMirror(tp);
+
+                if (site == null || site.getKind() != TypeKind.DECLARED)
+                    break;
+
+                Element siteEl = at.getTypes().asElement(site);
+
+                if (siteEl == null)
+                    break;
+
+                if (isStaticContext(at, tp)) {
+                    accessibility = accessibility.and(STATIC_ONLY);
+                }
+
+                for (ExecutableElement ee : ElementFilter.methodsIn(membersOf(at, siteEl.asType(), false))) {
+                    if (ee.getSimpleName().contentEquals(mst.getIdentifier())) {
+                        if (accessibility.test(ee)) {
+                            result.add(Pair.of(ee, (ExecutableType) at.getTypes().asMemberOf((DeclaredType) site, ee)));
+                        }
+                    }
+                }
+                break;
+            case IDENTIFIER:
+                IdentifierTree it = (IdentifierTree) select;
+                for (ExecutableElement ee : ElementFilter.methodsIn(scopeContent(at, at.trees().getScope(invocation), IDENTITY))) {
+                    if (ee.getSimpleName().contentEquals(it.getName())) {
+                        if (accessibility.test(ee)) {
+                            result.add(Pair.of(ee, (ExecutableType) ee.asType())); //XXX: proper site
+                        }
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+
+        return result;
+    }
+
+    private Iterable<Pair<ExecutableElement, ExecutableType>> newClassCandidates(AnalyzeTask at, TreePath newClassPath) {
+        NewClassTree nct = (NewClassTree) newClassPath.getLeaf();
+        Element type = at.trees().getElement(new TreePath(newClassPath.getParentPath(), nct.getIdentifier()));
+        TypeMirror targetType = at.trees().getTypeMirror(newClassPath);
+        if (targetType == null || targetType.getKind() != TypeKind.DECLARED) {
+            Iterable<TypeMirror> targetTypes = findTargetType(at, newClassPath);
+            if (targetTypes == null)
+                targetTypes = Collections.emptyList();
+            targetType =
+                    StreamSupport.stream(targetTypes.spliterator(), false)
+                                 .filter(t -> at.getTypes().asElement(t) == type)
+                                 .findAny()
+                                 .orElse(at.getTypes().erasure(type.asType()));
+        }
+        List<Pair<ExecutableElement, ExecutableType>> candidateConstructors = new ArrayList<>();
+        Predicate<Element> accessibility = createAccessibilityFilter(at, newClassPath);
+
+        if (targetType != null &&
+            targetType.getKind() == TypeKind.DECLARED &&
+            type != null &&
+            (type.getKind().isClass() || type.getKind().isInterface())) {
+            for (ExecutableElement constr : ElementFilter.constructorsIn(type.getEnclosedElements())) {
+                if (accessibility.test(constr)) {
+                    ExecutableType constrType =
+                            (ExecutableType) at.getTypes().asMemberOf((DeclaredType) targetType, constr);
+                    candidateConstructors.add(Pair.of(constr, constrType));
+                }
+            }
+        }
+
+        return candidateConstructors;
+    }
+
+    @Override
+    public String documentation(String code, int cursor) {
+        code = code.substring(0, cursor);
+        if (code.trim().isEmpty()) { //TODO: comment handling
+            code += ";";
+        }
+
+        if (guessKind(code) == Kind.IMPORT)
+            return null;
+
+        OuterWrap codeWrap = wrapInClass(Wrap.methodWrap(code));
+        AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap);
+        SourcePositions sp = at.trees().getSourcePositions();
+        CompilationUnitTree topLevel = at.cuTree();
+        TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(cursor));
+
+        if (tp == null)
+            return null;
+
+        TreePath prevPath = null;
+        while (tp != null && tp.getLeaf().getKind() != Kind.METHOD_INVOCATION && tp.getLeaf().getKind() != Kind.NEW_CLASS) {
+            prevPath = tp;
+            tp = tp.getParentPath();
+        }
+
+        if (tp == null)
+            return null;
+
+        Iterable<Pair<ExecutableElement, ExecutableType>> candidates;
+        List<? extends ExpressionTree> arguments;
+
+        if (tp.getLeaf().getKind() == Kind.METHOD_INVOCATION) {
+            MethodInvocationTree mit = (MethodInvocationTree) tp.getLeaf();
+            candidates = methodCandidates(at, tp);
+            arguments = mit.getArguments();
+        } else {
+            NewClassTree nct = (NewClassTree) tp.getLeaf();
+            candidates = newClassCandidates(at, tp);
+            arguments = nct.getArguments();
+        }
+
+        if (!isEmptyArgumentsContext(arguments)) {
+            List<TypeMirror> actuals = computeActualInvocationTypes(at, arguments, prevPath);
+            List<TypeMirror> fullActuals = actuals != null ? actuals : Collections.emptyList();
+
+            candidates =
+                    this.filterExecutableTypesByArguments(at, candidates, fullActuals)
+                        .stream()
+                        .filter(method -> parameterType(method.fst, method.snd, fullActuals.size(), true).findAny().isPresent())
+                        .collect(Collectors.toList());
+        }
+
+        return Util.stream(candidates)
+                .map(method -> Util.expunge(element2String(method.fst)))
+                .collect(joining("\n"));
+    }
+
+    private boolean isEmptyArgumentsContext(List<? extends ExpressionTree> arguments) {
+        if (arguments.size() == 1) {
+            Tree firstArgument = arguments.get(0);
+            return firstArgument.getKind() == Kind.ERRONEOUS;
+        }
+        return false;
+    }
+
+    private String element2String(Element el) {
+        switch (el.getKind()) {
+            case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
+                return ((TypeElement) el).getQualifiedName().toString();
+            case FIELD:
+                return element2String(el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType();
+            case ENUM_CONSTANT:
+                return element2String(el.getEnclosingElement()) + "." + el.getSimpleName();
+            case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE:
+                return el.getSimpleName() + ":" + el.asType();
+            case CONSTRUCTOR: case METHOD:
+                StringBuilder header = new StringBuilder();
+                header.append(element2String(el.getEnclosingElement()));
+                if (el.getKind() == ElementKind.METHOD) {
+                    header.append(".");
+                    header.append(el.getSimpleName());
+                }
+                header.append("(");
+                String sep = "";
+                ExecutableElement method = (ExecutableElement) el;
+                for (Iterator<? extends VariableElement> i = method.getParameters().iterator(); i.hasNext();) {
+                    VariableElement p = i.next();
+                    header.append(sep);
+                    if (!i.hasNext() && method.isVarArgs()) {
+                        header.append(unwrapArrayType(p.asType()));
+                        header.append("...");
+
+                    } else {
+                        header.append(p.asType());
+                    }
+                    header.append(" ");
+                    header.append(p.getSimpleName());
+                    sep = ", ";
+                }
+                header.append(")");
+                return header.toString();
+           default:
+                return el.toString();
+        }
+    }
+    private TypeMirror unwrapArrayType(TypeMirror arrayType) {
+        if (arrayType.getKind() == TypeKind.ARRAY) {
+            return ((ArrayType)arrayType).getComponentType();
+        }
+        return arrayType;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java
new file mode 100644
index 0000000..ace8d31
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import jdk.jshell.Key.StatementKey;
+
+/**
+ * Snippet for a statement.
+ * The Kind is {@link jdk.jshell.Snippet.Kind#STATEMENT}.
+ * <p>
+ * <code>StatementSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ * @jls 14.5: Statement.
+ */
+public class StatementSnippet extends Snippet {
+
+    StatementSnippet(StatementKey key, String userSource, Wrap guts) {
+        super(key, userSource, guts, null, SubKind.STATEMENT_SUBKIND);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java
new file mode 100644
index 0000000..a95e7a6
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.Context;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
+import static jdk.jshell.Util.*;
+import com.sun.source.tree.ImportTree;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.util.JavacMessages;
+import jdk.jshell.MemoryFileManager.OutputMemoryJavaFileObject;
+import java.util.Collections;
+import java.util.Locale;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
+import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
+import jdk.jshell.ClassTracker.ClassInfo;
+
+/**
+ * The primary interface to the compiler API.  Parsing, analysis, and
+ * compilation to class files (in memory).
+ * @author Robert Field
+ */
+class TaskFactory {
+
+    private final JavaCompiler compiler;
+    private final MemoryFileManager fileManager;
+    private final JShell state;
+    private String classpath = System.getProperty("java.class.path");
+
+    TaskFactory(JShell state) {
+        this.state = state;
+        this.compiler = ToolProvider.getSystemJavaCompiler();
+        if (compiler == null) {
+            throw new UnsupportedOperationException("Compiler not available, must be run with full JDK 9.");
+        }
+        if (!System.getProperty("java.specification.version").equals("1.9"))  {
+            throw new UnsupportedOperationException("Wrong compiler, must be run with full JDK 9.");
+        }
+        this.fileManager = new MemoryFileManager(
+                compiler.getStandardFileManager(null, null, null), state);
+    }
+
+    void addToClasspath(String path) {
+        classpath = classpath + File.pathSeparator + path;
+        List<String> args = new ArrayList<>();
+        args.add(classpath);
+        fileManager().handleOption("-classpath", args.iterator());
+    }
+
+    MemoryFileManager fileManager() {
+        return fileManager;
+    }
+
+    private interface SourceHandler<T> {
+
+        JavaFileObject sourceToFileObject(MemoryFileManager fm, T t);
+
+        Diag diag(Diagnostic<? extends JavaFileObject> d);
+    }
+
+    private class StringSourceHandler implements SourceHandler<String> {
+
+        @Override
+        public JavaFileObject sourceToFileObject(MemoryFileManager fm, String src) {
+            return fm.createSourceFileObject(src, "$NeverUsedName$", src);
+        }
+
+        @Override
+        public Diag diag(final Diagnostic<? extends JavaFileObject> d) {
+            return new Diag() {
+
+                @Override
+                public boolean isError() {
+                    return d.getKind() == Diagnostic.Kind.ERROR;
+                }
+
+                @Override
+                public long getPosition() {
+                    return d.getPosition();
+                }
+
+                @Override
+                public long getStartPosition() {
+                    return d.getStartPosition();
+                }
+
+                @Override
+                public long getEndPosition() {
+                    return d.getEndPosition();
+                }
+
+                @Override
+                public String getCode() {
+                    return d.getCode();
+                }
+
+                @Override
+                public String getMessage(Locale locale) {
+                    return expunge(d.getMessage(locale));
+                }
+
+                @Override
+                Unit unitOrNull() {
+                    return null;
+                }
+            };
+        }
+    }
+
+    private class WrapSourceHandler implements SourceHandler<OuterWrap> {
+
+        final OuterWrap wrap;
+
+        WrapSourceHandler(OuterWrap wrap) {
+            this.wrap = wrap;
+        }
+
+        @Override
+        public JavaFileObject sourceToFileObject(MemoryFileManager fm, OuterWrap w) {
+            return fm.createSourceFileObject(w, w.classFullName(), w.wrapped());
+        }
+
+        @Override
+        public Diag diag(Diagnostic<? extends JavaFileObject> d) {
+            return wrap.wrapDiag(d);
+        }
+    }
+
+    private class UnitSourceHandler implements SourceHandler<Unit> {
+
+        @Override
+        public JavaFileObject sourceToFileObject(MemoryFileManager fm, Unit u) {
+            return fm.createSourceFileObject(u,
+                    state.maps.classFullName(u.snippet()),
+                    u.snippet().outerWrap().wrapped());
+        }
+
+        @Override
+        public Diag diag(Diagnostic<? extends JavaFileObject> d) {
+            SourceMemoryJavaFileObject smjfo = (SourceMemoryJavaFileObject) d.getSource();
+            Unit u = (Unit) smjfo.getOrigin();
+            return u.snippet().outerWrap().wrapDiag(d);
+        }
+    }
+
+    /**
+     * Parse a snippet of code (as a String) using the parser subclass.  Return
+     * the parse tree (and errors).
+     */
+    class ParseTask extends BaseTask {
+
+        private final CompilationUnitTree cut;
+        private final List<? extends Tree> units;
+
+        ParseTask(final String source) {
+            super(Stream.of(source),
+                    new StringSourceHandler(),
+                    "-XDallowStringFolding=false", "-proc:none");
+            ReplParserFactory.instance(getContext());
+            Iterable<? extends CompilationUnitTree> asts = parse();
+            Iterator<? extends CompilationUnitTree> it = asts.iterator();
+            if (it.hasNext()) {
+                this.cut = it.next();
+                List<? extends ImportTree> imps = cut.getImports();
+                this.units = !imps.isEmpty() ? imps : cut.getTypeDecls();
+            } else {
+                this.cut = null;
+                this.units = Collections.emptyList();
+            }
+        }
+
+        private Iterable<? extends CompilationUnitTree> parse() {
+            try {
+                return task.parse();
+            } catch (Exception ex) {
+                throw new InternalError("Exception during parse - " + ex.getMessage(), ex);
+            }
+        }
+
+        List<? extends Tree> units() {
+            return units;
+        }
+
+        @Override
+        CompilationUnitTree cuTree() {
+            return cut;
+        }
+    }
+
+    /**
+     * Run the normal "analyze()" pass of the compiler over the wrapped snippet.
+     */
+    class AnalyzeTask extends BaseTask {
+
+        private final CompilationUnitTree cut;
+
+        AnalyzeTask(final OuterWrap wrap) {
+            this(Stream.of(wrap),
+                    new WrapSourceHandler(wrap),
+                    "-XDshouldStopPolicy=FLOW", "-proc:none");
+        }
+
+        AnalyzeTask(final Collection<Unit> units) {
+            this(units.stream(), new UnitSourceHandler(),
+                    "-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", "-proc:none");
+        }
+
+        <T>AnalyzeTask(final Stream<T> stream, SourceHandler<T> sourceHandler,
+                String... extraOptions) {
+            super(stream, sourceHandler, extraOptions);
+            Iterator<? extends CompilationUnitTree> cuts = analyze().iterator();
+            if (cuts.hasNext()) {
+                this.cut = cuts.next();
+                //proc.debug("AnalyzeTask element=%s  cutp=%s  cut=%s\n", e, cutp, cut);
+            } else {
+                this.cut = null;
+                //proc.debug("AnalyzeTask -- no elements -- %s\n", getDiagnostics());
+            }
+        }
+
+        private Iterable<? extends CompilationUnitTree> analyze() {
+            try {
+                Iterable<? extends CompilationUnitTree> cuts = task.parse();
+                task.analyze();
+                return cuts;
+            } catch (Exception ex) {
+                throw new InternalError("Exception during analyze - " + ex.getMessage(), ex);
+            }
+        }
+
+        @Override
+        CompilationUnitTree cuTree() {
+            return cut;
+        }
+
+        Elements getElements() {
+            return task.getElements();
+        }
+
+        javax.lang.model.util.Types getTypes() {
+            return task.getTypes();
+        }
+    }
+
+    /**
+     * Unit the wrapped snippet to class files.
+     */
+    class CompileTask extends BaseTask {
+
+        private final Map<Unit, List<OutputMemoryJavaFileObject>> classObjs = new HashMap<>();
+
+        CompileTask(Collection<Unit> units) {
+            super(units.stream(), new UnitSourceHandler(),
+                    "-Xlint:unchecked", "-proc:none");
+        }
+
+        boolean compile() {
+            fileManager.registerClassFileCreationListener(this::listenForNewClassFile);
+            boolean result = task.call();
+            fileManager.registerClassFileCreationListener(null);
+            return result;
+        }
+
+
+        List<ClassInfo> classInfoList(Unit u) {
+            List<OutputMemoryJavaFileObject> l = classObjs.get(u);
+            if (l == null) return Collections.emptyList();
+            return l.stream()
+                    .map(fo -> state.classTracker.classInfo(fo.getName(), fo.getBytes()))
+                    .collect(Collectors.toList());
+        }
+
+        private void listenForNewClassFile(OutputMemoryJavaFileObject jfo, JavaFileManager.Location location,
+                String className, JavaFileObject.Kind kind, FileObject sibling) {
+            //debug("listenForNewClassFile %s loc=%s kind=%s\n", className, location, kind);
+            if (location == CLASS_OUTPUT) {
+                state.debug(DBG_GEN, "Compiler generating class %s\n", className);
+                Unit u = ((sibling instanceof SourceMemoryJavaFileObject)
+                        && (((SourceMemoryJavaFileObject) sibling).getOrigin() instanceof Unit))
+                        ? (Unit) ((SourceMemoryJavaFileObject) sibling).getOrigin()
+                        : null;
+                classObjs.compute(u, (k, v) -> (v == null)? new ArrayList<>() : v)
+                        .add(jfo);
+            }
+        }
+
+        @Override
+        CompilationUnitTree cuTree() {
+            throw new UnsupportedOperationException("Not supported.");
+        }
+    }
+
+    abstract class BaseTask {
+
+        final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+        final JavacTaskImpl task;
+        private DiagList diags = null;
+        private final SourceHandler<?> sourceHandler;
+        private final Context context = new Context();
+        private Types types;
+        private JavacMessages messages;
+        private Trees trees;
+
+        private <T>BaseTask(Stream<T> inputs,
+                //BiFunction<MemoryFileManager, T, JavaFileObject> sfoCreator,
+                SourceHandler<T> sh,
+                String... extraOptions) {
+            this.sourceHandler = sh;
+            List<String> options = Arrays.asList(extraOptions);
+            Iterable<? extends JavaFileObject> compilationUnits = inputs
+                            .map(in -> sh.sourceToFileObject(fileManager, in))
+                            .collect(Collectors.toList());
+            this.task = (JavacTaskImpl) ((JavacTool) compiler).getTask(null,
+                    fileManager, diagnostics, options, null,
+                    compilationUnits, context);
+        }
+
+        abstract CompilationUnitTree cuTree();
+
+        Diag diag(Diagnostic<? extends JavaFileObject> diag) {
+            return sourceHandler.diag(diag);
+        }
+
+        Context getContext() {
+            return context;
+        }
+
+        Types types() {
+            if (types == null) {
+                types = Types.instance(context);
+            }
+            return types;
+        }
+
+        JavacMessages messages() {
+            if (messages == null) {
+                messages = JavacMessages.instance(context);
+            }
+            return messages;
+        }
+
+        Trees trees() {
+            if (trees == null) {
+                trees = Trees.instance(task);
+            }
+            return trees;
+        }
+
+        // ------------------ diags functionality
+
+        DiagList getDiagnostics() {
+            if (diags == null) {
+                LinkedHashMap<String, Diag> diagMap = new LinkedHashMap<>();
+                for (Diagnostic<? extends JavaFileObject> in : diagnostics.getDiagnostics()) {
+                    Diag d = diag(in);
+                    String uniqueKey = d.getCode() + ":" + d.getPosition() + ":" + d.getMessage(null);
+                    diagMap.put(uniqueKey, d);
+                }
+                diags = new DiagList(diagMap.values());
+            }
+            return diags;
+        }
+
+        boolean hasErrors() {
+            return getDiagnostics().hasErrors();
+        }
+
+        String shortErrorMessage() {
+            StringBuilder sb = new StringBuilder();
+            for (Diag diag : getDiagnostics()) {
+                for (String line : diag.getMessage(null).split("\\r?\\n")) {
+                    if (!line.trim().startsWith("location:")) {
+                        sb.append(line);
+                    }
+                }
+            }
+            return sb.toString();
+        }
+
+        void debugPrintDiagnostics(String src) {
+            for (Diag diag : getDiagnostics()) {
+                state.debug(DBG_GEN, "ERROR --\n");
+                for (String line : diag.getMessage(null).split("\\r?\\n")) {
+                    if (!line.trim().startsWith("location:")) {
+                        state.debug(DBG_GEN, "%s\n", line);
+                    }
+                }
+                int start = (int) diag.getStartPosition();
+                int end = (int) diag.getEndPosition();
+                if (src != null) {
+                    String[] srcLines = src.split("\\r?\\n");
+                    for (String line : srcLines) {
+                        state.debug(DBG_GEN, "%s\n", line);
+                    }
+
+                    StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < start; ++i) {
+                        sb.append(' ');
+                    }
+                    sb.append('^');
+                    if (end > start) {
+                        for (int i = start + 1; i < end; ++i) {
+                            sb.append('-');
+                        }
+                        sb.append('^');
+                    }
+                    state.debug(DBG_GEN, "%s\n", sb.toString());
+                }
+                state.debug(DBG_GEN, "printDiagnostics start-pos = %d ==> %d -- wrap = %s\n",
+                        diag.getStartPosition(), start, this);
+                state.debug(DBG_GEN, "Code: %s\n", diag.getCode());
+                state.debug(DBG_GEN, "Pos: %d (%d - %d) -- %s\n", diag.getPosition(),
+                        diag.getStartPosition(), diag.getEndPosition(), diag.getMessage(null));
+            }
+        }
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java
new file mode 100644
index 0000000..5c5840f
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDependencyScanner.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.ImportTree;
+import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.PackageTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreeScanner;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import javax.lang.model.element.Name;
+
+/**
+ * Search a compiler API parse tree for dependencies.
+ */
+class TreeDependencyScanner extends TreeScanner<Void, Set<String>> {
+
+    private final Set<String> decl = new HashSet<>();
+    private final Set<String> body = new HashSet<>();
+
+    public void scan(Tree node) {
+        scan(node, decl);
+    }
+
+    public Collection<String> declareReferences() {
+        return decl;
+    }
+
+    public Collection<String> bodyReferences() {
+        return body;
+    }
+
+    private void add(Set<String> p, Name name) {
+        p.add(name.toString());
+    }
+
+    // -- Differentiate declaration references from body references ---
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitClass(ClassTree node, Set<String> p) {
+        scan(node.getModifiers(), p);
+        scan(node.getTypeParameters(), p);
+        scan(node.getExtendsClause(), p);
+        scan(node.getImplementsClause(), p);
+        scan(node.getMembers(), body);
+        return null;
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitMethod(MethodTree node, Set<String> p) {
+        scan(node.getModifiers(), p);
+        scan(node.getReturnType(), p);
+        scan(node.getTypeParameters(), p);
+        scan(node.getParameters(), p);
+        scan(node.getReceiverParameter(), p);
+        scan(node.getThrows(), p);
+        scan(node.getBody(), body);
+        scan(node.getDefaultValue(), body);
+        return null;
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitVariable(VariableTree node, Set<String> p) {
+        scan(node.getModifiers(), p);
+        scan(node.getType(), p);
+        scan(node.getNameExpression(), p);
+        scan(node.getInitializer(), body);
+        return null;
+    }
+
+    // --- Ignore these ---
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitPackage(PackageTree node, Set<String> p) {
+        return null;
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitImport(ImportTree node, Set<String> p) {
+        return null;
+    }
+
+
+    // -- Actual Symbol names ---
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitMemberSelect(MemberSelectTree node, Set<String> p) {
+        add(p, node.getIdentifier());
+        return super.visitMemberSelect(node, p);
+    }
+
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public Void visitIdentifier(IdentifierTree node, Set<String> p) {
+        add(p, node.getName());
+        return super.visitIdentifier(node, p);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java
new file mode 100644
index 0000000..0235f34
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TreeDissector.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.ReturnTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.util.JavacMessages;
+import com.sun.tools.javac.util.Name;
+import static jdk.jshell.Util.isDoIt;
+import jdk.jshell.Wrap.Range;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.BinaryOperator;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * Utilities for analyzing compiler API parse trees.
+ * @author Robert Field
+ */
+
+class TreeDissector {
+
+    private static final String OBJECT_TYPE = "Object";
+
+    static class ExpressionInfo {
+
+        boolean isNonVoid;
+        String typeName;
+        ExpressionTree tree;
+        String signature;
+    }
+
+    private final TaskFactory.BaseTask bt;
+    private ClassTree firstClass;
+    private SourcePositions theSourcePositions = null;
+
+    TreeDissector(TaskFactory.BaseTask bt) {
+        this.bt = bt;
+    }
+
+
+    ClassTree firstClass() {
+        if (firstClass == null) {
+            firstClass = computeFirstClass();
+        }
+        return firstClass;
+    }
+
+    CompilationUnitTree cuTree() {
+        return bt.cuTree();
+    }
+
+    Types types() {
+        return bt.types();
+    }
+
+    Trees trees() {
+        return bt.trees();
+    }
+
+    SourcePositions getSourcePositions() {
+        if (theSourcePositions == null) {
+            theSourcePositions = trees().getSourcePositions();
+        }
+        return theSourcePositions;
+    }
+
+    int getStartPosition(Tree tree) {
+        return (int) getSourcePositions().getStartPosition(cuTree(), tree);
+    }
+
+    int getEndPosition(Tree tree) {
+        return (int) getSourcePositions().getEndPosition(cuTree(), tree);
+    }
+
+    Range treeToRange(Tree tree) {
+        return new Range(getStartPosition(tree), getEndPosition(tree));
+    }
+
+    Range treeListToRange(List<? extends Tree> treeList) {
+        int start = Integer.MAX_VALUE;
+        int end = -1;
+        for (Tree t : treeList) {
+            int tstart = getStartPosition(t);
+            int tend = getEndPosition(t);
+            if (tstart < start) {
+                start = tstart;
+            }
+            if (tend > end) {
+                end = tend;
+            }
+        }
+        if (start == Integer.MAX_VALUE) {
+            return null;
+        }
+        return new Range(start, end);
+    }
+
+    Tree firstClassMember() {
+        if (firstClass() != null) {
+            //TODO: missing classes
+            for (Tree mem : firstClass().getMembers()) {
+                if (mem.getKind() == Tree.Kind.VARIABLE) {
+                    return mem;
+                }
+                if (mem.getKind() == Tree.Kind.METHOD) {
+                    MethodTree mt = (MethodTree) mem;
+                    if (!isDoIt(mt.getName()) && !mt.getName().toString().equals("<init>")) {
+                        return mt;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    StatementTree firstStatement() {
+        if (firstClass() != null) {
+            for (Tree mem : firstClass().getMembers()) {
+                if (mem.getKind() == Tree.Kind.METHOD) {
+                    MethodTree mt = (MethodTree) mem;
+                    if (isDoIt(mt.getName())) {
+                        List<? extends StatementTree> stmts = mt.getBody().getStatements();
+                        if (!stmts.isEmpty()) {
+                            return stmts.get(0);
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    VariableTree firstVariable() {
+        if (firstClass() != null) {
+            for (Tree mem : firstClass().getMembers()) {
+                if (mem.getKind() == Tree.Kind.VARIABLE) {
+                    VariableTree vt = (VariableTree) mem;
+                    return vt;
+                }
+            }
+        }
+        return null;
+    }
+
+    private ClassTree computeFirstClass() {
+        if (cuTree() == null) {
+            return null;
+        }
+        for (Tree decl : cuTree().getTypeDecls()) {
+            if (decl.getKind() == Tree.Kind.CLASS || decl.getKind() == Tree.Kind.INTERFACE) {
+                return (ClassTree) decl;
+            }
+        }
+        return null;
+    }
+
+    ExpressionInfo typeOfReturnStatement(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass) {
+        ExpressionInfo ei = new ExpressionInfo();
+        Tree unitTree = firstStatement();
+        if (unitTree instanceof ReturnTree) {
+            ei.tree = ((ReturnTree) unitTree).getExpression();
+            if (ei.tree != null) {
+                TreePath viPath = trees().getPath(cuTree(), ei.tree);
+                if (viPath != null) {
+                    TypeMirror tm = trees().getTypeMirror(viPath);
+                    if (tm != null) {
+                        Type type = (Type)tm;
+                        TypePrinter tp = new TypePrinter(messages, fullClassNameAndPackageToClass, type);
+                        ei.typeName = tp.visit(type, Locale.getDefault());
+                        switch (tm.getKind()) {
+                            case VOID:
+                            case NONE:
+                            case ERROR:
+                            case OTHER:
+                                break;
+                            case NULL:
+                                ei.isNonVoid = true;
+                                ei.typeName = OBJECT_TYPE;
+                                break;
+                            default: {
+                                ei.isNonVoid = true;
+                                break;
+
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return ei;
+    }
+
+    String typeOfMethod() {
+        Tree unitTree = firstClassMember();
+        if (unitTree instanceof JCMethodDecl) {
+            JCMethodDecl mtree = (JCMethodDecl) unitTree;
+            Type mt = types().erasure(mtree.type);
+            if (mt instanceof MethodType) {
+                return signature(types(), (MethodType) mt);
+            }
+        }
+        return null;
+    }
+
+    static String signature(Types types, MethodType mt) {
+        TDSignatureGenerator sg = new TDSignatureGenerator(types);
+        sg.assembleSig(mt);
+        return sg.toString();
+    }
+
+    /**
+     * Signature Generation
+     */
+    private static class TDSignatureGenerator extends Types.SignatureGenerator {
+
+        /**
+         * An output buffer for type signatures.
+         */
+        StringBuilder sb = new StringBuilder();
+
+        TDSignatureGenerator(Types types) {
+            super(types);
+        }
+
+        @Override
+        protected void append(char ch) {
+            sb.append(ch);
+        }
+
+        @Override
+        protected void append(byte[] ba) {
+            sb.append(new String(ba));
+        }
+
+        @Override
+        protected void append(Name name) {
+            sb.append(name);
+        }
+
+        @Override
+        public String toString() {
+            return sb.toString();
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypeDeclSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypeDeclSnippet.java
new file mode 100644
index 0000000..6d29087
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypeDeclSnippet.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.Collection;
+import jdk.jshell.Key.TypeDeclKey;
+
+/**
+ * Snippet for a type definition (a class, interface, enum, or annotation
+ * interface definition).
+ * The Kind is {@link jdk.jshell.Snippet.Kind#TYPE_DECL}.
+ * <p>
+ * <code>TypeDeclSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ */
+public class TypeDeclSnippet extends DeclarationSnippet {
+
+    TypeDeclSnippet(TypeDeclKey key, String userSource, Wrap guts,
+            String unitName, SubKind subkind, Wrap corralled,
+            Collection<String> declareReferences,
+            Collection<String> bodyReferences) {
+        super(key, userSource, guts, unitName, subkind, corralled, declareReferences, bodyReferences);
+    }
+
+    /**** internal access ****/
+
+    @Override
+    TypeDeclKey key() {
+        return (TypeDeclKey) super.key();
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java
new file mode 100644
index 0000000..2ac9530
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypePrinter.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import static com.sun.tools.javac.code.Flags.COMPOUND;
+import static com.sun.tools.javac.code.Kinds.Kind.PCK;
+import com.sun.tools.javac.code.Printer;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.util.JavacMessages;
+import java.util.Locale;
+import java.util.function.BinaryOperator;
+
+/**
+ * Print types in source form.
+ */
+class TypePrinter extends Printer {
+
+    private final JavacMessages messages;
+    private final BinaryOperator<String> fullClassNameAndPackageToClass;
+    private final Type typeToPrint;
+
+    TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass, Type typeToPrint) {
+        this.messages = messages;
+        this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
+        this.typeToPrint = typeToPrint;
+    }
+
+    @Override
+    protected String localize(Locale locale, String key, Object... args) {
+        return messages.getLocalizedString(locale, key, args);
+    }
+
+    @Override
+    protected String capturedVarId(Type.CapturedType t, Locale locale) {
+        throw new InternalError("should never call this");
+    }
+
+    @Override
+    public String visitCapturedType(Type.CapturedType t, Locale locale) {
+        if (t == typeToPrint) {
+            return visit(t.getUpperBound(), locale);
+        } else {
+            return visit(t.wildcard, locale);
+        }
+    }
+
+    @Override
+    public String visitType(Type t, Locale locale) {
+        String s = (t.tsym == null || t.tsym.name == null)
+                ? "Object" // none
+                : t.tsym.name.toString();
+        return s;
+    }
+
+    /**
+     * Converts a class name into a (possibly localized) string. Anonymous
+     * inner classes get converted into a localized string.
+     *
+     * @param t the type of the class whose name is to be rendered
+     * @param longform if set, the class' fullname is displayed - if unset the
+     * short name is chosen (w/o package)
+     * @param locale the locale in which the string is to be rendered
+     * @return localized string representation
+     */
+    @Override
+    protected String className(ClassType t, boolean longform, Locale locale) {
+        Symbol sym = t.tsym;
+        if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
+            /***
+            StringBuilder s = new StringBuilder(visit(t.supertype_field, locale));
+            for (List<Type> is = t.interfaces_field; is.nonEmpty(); is = is.tail) {
+                s.append('&');
+                s.append(visit(is.head, locale));
+            }
+            return s.toString();
+            ***/
+            return "Object";
+        } else if (sym.name.length() == 0) {
+            // Anonymous
+            String s;
+            ClassType norm = (ClassType) t.tsym.type;
+            if (norm == null) {
+                s = "object";
+            } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
+                s = visit(norm.interfaces_field.head, locale);
+            } else {
+                s = visit(norm.supertype_field, locale);
+            }
+            return s;
+        } else if (longform) {
+            String pkg = "";
+            for (Symbol psym = sym; psym != null; psym = psym.owner) {
+                if (psym.kind == PCK) {
+                    pkg = psym.getQualifiedName().toString();
+                    break;
+                }
+            }
+            return fullClassNameAndPackageToClass.apply(
+                    sym.getQualifiedName().toString(),
+                    pkg
+            );
+        } else {
+            return sym.name.toString();
+        }
+    }
+
+    @Override
+    public String visitClassSymbol(ClassSymbol sym, Locale locale) {
+        return sym.name.isEmpty()
+                ? sym.flatname.toString() // Anonymous
+                : sym.fullname.toString();
+    }
+
+    @Override
+    public String visitPackageSymbol(PackageSymbol s, Locale locale) {
+        return s.isUnnamed()
+                ? ""   // Unnamed package
+                : s.fullname.toString();
+    }
+
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java
new file mode 100644
index 0000000..c146a6f
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
+import com.sun.jdi.ReferenceType;
+import jdk.jshell.Snippet.Kind;
+import jdk.jshell.Snippet.Status;
+import jdk.jshell.Snippet.SubKind;
+import jdk.jshell.TaskFactory.AnalyzeTask;
+import jdk.jshell.ClassTracker.ClassInfo;
+import jdk.jshell.TaskFactory.CompileTask;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_EVNT;
+import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
+import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
+import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
+import static jdk.jshell.Snippet.Status.REJECTED;
+import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Util.expunge;
+
+/**
+ * Tracks the compilation and load of a new or updated snippet.
+ * @author Robert Field
+ */
+final class Unit {
+
+    private final JShell state;
+    private final Snippet si;
+    private final Snippet siOld;
+    private final boolean isDependency;
+    private final boolean isNew;
+    private final Snippet causalSnippet;
+    private final DiagList generatedDiagnostics;
+
+    private int seq;
+    private int seqInitial;
+    private Wrap activeGuts;
+    private Status status;
+    private Status prevStatus;
+    private boolean signatureChanged;
+    private DiagList compilationDiagnostics;
+    private DiagList recompilationDiagnostics = null;
+    private List<String> unresolved;
+    private SnippetEvent replaceOldEvent;
+    private List<SnippetEvent> secondaryEvents;
+    private boolean isAttemptingCorral;
+    private List<ClassInfo> toRedefine;
+    private boolean dependenciesNeeded;
+
+    Unit(JShell state, Snippet si, Snippet causalSnippet,
+            DiagList generatedDiagnostics) {
+        this.state = state;
+        this.si = si;
+        this.isDependency = causalSnippet != null;
+        this.siOld = isDependency
+                ? si
+                : state.maps.getSnippet(si.key());
+        this.isNew = siOld == null;
+        this.causalSnippet = causalSnippet;
+        this.generatedDiagnostics = generatedDiagnostics;
+
+        this.seq = isNew? 0 : siOld.sequenceNumber();
+        this.seqInitial = seq;
+        this.prevStatus = (isNew || isDependency)
+                ? si.status()
+                : siOld.status();
+        si.setSequenceNumber(seq);
+    }
+
+    // Drop entry
+    Unit(JShell state, Snippet si) {
+        this.state = state;
+        this.si = si;
+        this.siOld = null;
+        this.isDependency = false;
+        this.isNew = false;
+        this.causalSnippet = null;
+        this.generatedDiagnostics = new DiagList();
+        this.prevStatus = si.status();
+        si.setDropped();
+        this.status = si.status();
+    }
+
+    @Override
+    public int hashCode() {
+        return si.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return (o instanceof Unit)
+                ? si.equals(((Unit) o).si)
+                : false;
+    }
+
+    Snippet snippet() {
+        return si;
+    }
+
+    boolean isDependency() {
+        return isDependency;
+    }
+
+    boolean isNew() {
+        return isNew;
+    }
+
+    boolean isRedundant() {
+        return !isNew && !isDependency() && !si.isExecutable() &&
+                prevStatus.isDefined &&
+                siOld.source().equals(si.source());
+    }
+
+    void initialize(Collection<Unit> working) {
+        isAttemptingCorral = false;
+        dependenciesNeeded = false;
+        toRedefine = null; // assure NPE if classToLoad not called
+        activeGuts = si.guts();
+        markOldDeclarationOverwritten();
+        setWrap(working, working);
+    }
+
+    void setWrap(Collection<Unit> except, Collection<Unit> plus) {
+        si.setOuterWrap(isImport()
+                ? OuterWrap.wrapImport(si.source(), activeGuts)
+                : state.eval.wrapInClass(si,
+                        except.stream().map(u -> u.snippet().key()).collect(toSet()),
+                        activeGuts,
+                        plus.stream().map(u -> u.snippet())
+                                .filter(sn -> sn != si)
+                                .collect(toList())));
+    }
+
+    void setDiagnostics(AnalyzeTask ct) {
+        setDiagnostics(ct.getDiagnostics().ofUnit(this));
+    }
+
+    void setDiagnostics(DiagList diags) {
+        compilationDiagnostics = diags;
+        UnresolvedExtractor ue = new UnresolvedExtractor(diags);
+        unresolved = ue.unresolved();
+        state.debug(DBG_GEN, "++setCompilationInfo() %s\n%s\n-- diags: %s\n",
+                si, si.outerWrap().wrapped(), diags);
+    }
+
+    private boolean isRecoverable() {
+        // Unit failed, use corralling if it is defined on this Snippet,
+        // and either all the errors are resolution errors or this is a
+        // redeclare of an existing method
+        return compilationDiagnostics.hasErrors()
+                && si instanceof DeclarationSnippet
+                && (isDependency()
+                    || (si.subKind() != SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND
+                        && compilationDiagnostics.hasResolutionErrorsAndNoOthers()));
+    }
+
+    /**
+     * If it meets the conditions for corralling, install the corralled wrap
+     * @return true is the corralled wrap was installed
+     */
+    boolean corralIfNeeded(Collection<Unit> working) {
+        if (isRecoverable()
+                && si.corralled() != null) {
+            activeGuts = si.corralled();
+            setWrap(working, working);
+            return isAttemptingCorral = true;
+        }
+        return isAttemptingCorral = false;
+    }
+
+    void setCorralledDiagnostics(AnalyzeTask cct) {
+        // set corralled diagnostics, but don't reset unresolved
+        recompilationDiagnostics = cct.getDiagnostics().ofUnit(this);
+        state.debug(DBG_GEN, "++recomp %s\n%s\n-- diags: %s\n",
+                si, si.outerWrap().wrapped(), recompilationDiagnostics);
+    }
+
+    boolean smashingErrorDiagnostics(CompileTask ct) {
+        if (isDefined()) {
+            // set corralled diagnostics, but don't reset unresolved
+            DiagList dl = ct.getDiagnostics().ofUnit(this);
+            if (dl.hasErrors()) {
+                setDiagnostics(dl);
+                status = RECOVERABLE_NOT_DEFINED;
+                // overwrite orginal bytes
+                state.debug(DBG_GEN, "++smashingErrorDiagnostics %s\n%s\n-- diags: %s\n",
+                        si, si.outerWrap().wrapped(), dl);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void setStatus() {
+        if (!compilationDiagnostics.hasErrors()) {
+            status = VALID;
+        } else if (isRecoverable()) {
+            if (isAttemptingCorral && !recompilationDiagnostics.hasErrors()) {
+                status = RECOVERABLE_DEFINED;
+            } else {
+                status = RECOVERABLE_NOT_DEFINED;
+            }
+        } else {
+            status = REJECTED;
+        }
+        checkForOverwrite();
+
+        state.debug(DBG_GEN, "setStatus() %s - status: %s\n",
+                si, status);
+    }
+
+    /**
+     * Must be called for each unit
+     * @return
+     */
+    boolean isDefined() {
+        return status.isDefined;
+    }
+
+    /**
+     * Process the class information from the last compile.
+     * Requires loading of returned list.
+     * @return the list of classes to load
+     */
+    Stream<ClassInfo> classesToLoad(List<ClassInfo> cil) {
+        toRedefine = new ArrayList<>();
+        List<ClassInfo> toLoad = new ArrayList<>();
+        if (status.isDefined && !isImport()) {
+            cil.stream().forEach(ci -> {
+                if (!ci.isLoaded()) {
+                    if (ci.getReferenceTypeOrNull() == null) {
+                        toLoad.add(ci);
+                        ci.setLoaded();
+                        dependenciesNeeded = true;
+                    } else {
+                        toRedefine.add(ci);
+                    }
+                }
+            });
+        }
+        return toLoad.stream();
+    }
+
+    /**
+     * Redefine classes needing redefine.
+     * classesToLoad() must be called first.
+     * @return true if all redefines succeeded (can be vacuously true)
+     */
+    boolean doRedefines() {
+         if (toRedefine.isEmpty()) {
+            return true;
+        }
+        Map<ReferenceType, byte[]> mp = toRedefine.stream()
+                .collect(toMap(ci -> ci.getReferenceTypeOrNull(), ci -> ci.getBytes()));
+        if (state.executionControl().commandRedefine(mp)) {
+            // success, mark as loaded
+            toRedefine.stream().forEach(ci -> ci.setLoaded());
+            return true;
+        } else {
+            // failed to redefine
+            return false;
+        }
+    }
+
+    void markForReplacement() {
+        // increment for replace class wrapper
+        si.setSequenceNumber(++seq);
+    }
+
+    private boolean isImport() {
+        return si.kind() == Kind.IMPORT;
+    }
+
+    private boolean sigChanged() {
+        return (status.isDefined != prevStatus.isDefined)
+                || (seq != seqInitial && status.isDefined)
+                || signatureChanged;
+    }
+
+    Stream<Unit> effectedDependents() {
+        return sigChanged() || dependenciesNeeded || status == RECOVERABLE_NOT_DEFINED
+                ? dependents()
+                : Stream.empty();
+    }
+
+    Stream<Unit> dependents() {
+        return state.maps.getDependents(si)
+                    .stream()
+                    .filter(xsi -> xsi != si && xsi.status().isActive)
+                    .map(xsi -> new Unit(state, xsi, si, new DiagList()));
+    }
+
+    void finish() {
+        recordCompilation();
+        state.maps.installSnippet(si);
+    }
+
+    private void markOldDeclarationOverwritten() {
+        if (si != siOld && siOld != null && siOld.status().isActive) {
+            // Mark the old declaraion as replaced
+            replaceOldEvent = new SnippetEvent(siOld,
+                    siOld.status(), OVERWRITTEN,
+                    false, si, null, null);
+            siOld.setOverwritten();
+        }
+    }
+
+    private DiagList computeDiagnostics() {
+        DiagList diagnostics = new DiagList();
+        DiagList diags = compilationDiagnostics;
+        if (status == RECOVERABLE_DEFINED || status == RECOVERABLE_NOT_DEFINED) {
+            UnresolvedExtractor ue = new UnresolvedExtractor(diags);
+            diagnostics.addAll(ue.otherAll());
+        } else {
+            unresolved = Collections.emptyList();
+            diagnostics.addAll(diags);
+        }
+        diagnostics.addAll(generatedDiagnostics);
+        return diagnostics;
+    }
+
+    private void recordCompilation() {
+        state.maps.mapDependencies(si);
+        DiagList diags = computeDiagnostics();
+        si.setCompilationStatus(status, unresolved, diags);
+        state.debug(DBG_GEN, "recordCompilation: %s -- status %s, unresolved %s\n",
+                si, status, unresolved);
+    }
+
+    private void checkForOverwrite() {
+        secondaryEvents = new ArrayList<>();
+        if (replaceOldEvent != null) secondaryEvents.add(replaceOldEvent);
+
+        // Defined methods can overwrite methods of other (equivalent) snippets
+        if (si.kind() == Kind.METHOD && status.isDefined) {
+            String oqpt = ((MethodSnippet) si).qualifiedParameterTypes();
+            String nqpt = computeQualifiedParameterTypes(si);
+            if (!nqpt.equals(oqpt)) {
+                ((MethodSnippet) si).setQualifiedParamaterTypes(nqpt);
+                Status overwrittenStatus = overwriteMatchingMethod(si);
+                if (overwrittenStatus != null) {
+                    prevStatus = overwrittenStatus;
+                    signatureChanged = true;
+                }
+            }
+        }
+    }
+
+    // Check if there is a method whose user-declared parameter types are
+    // different (and thus has a different snippet) but whose compiled parameter
+    // types are the same. if so, consider it an overwrite replacement.
+    private Status overwriteMatchingMethod(Snippet si) {
+        String qpt = ((MethodSnippet) si).qualifiedParameterTypes();
+
+        // Look through all methods for a method of the same name, with the
+        // same computed qualified parameter types
+        Status overwrittenStatus = null;
+        for (MethodSnippet sn : state.methods()) {
+            if (sn != null && sn != si && sn.status().isActive && sn.name().equals(si.name())) {
+                if (qpt.equals(sn.qualifiedParameterTypes())) {
+                    overwrittenStatus = sn.status();
+                    SnippetEvent se = new SnippetEvent(
+                            sn, overwrittenStatus, OVERWRITTEN,
+                            false, si, null, null);
+                    sn.setOverwritten();
+                    secondaryEvents.add(se);
+                    state.debug(DBG_EVNT,
+                            "Overwrite event #%d -- key: %s before: %s status: %s sig: %b cause: %s\n",
+                            secondaryEvents.size(), se.snippet(), se.previousStatus(),
+                            se.status(), se.isSignatureChange(), se.causeSnippet());
+                }
+            }
+        }
+        return overwrittenStatus;
+    }
+
+    private String computeQualifiedParameterTypes(Snippet si) {
+        MethodSnippet msi = (MethodSnippet) si;
+        String qpt;
+        AnalyzeTask at = state.taskFactory.new AnalyzeTask(msi.outerWrap());
+        String rawSig = new TreeDissector(at).typeOfMethod();
+        String signature = expunge(rawSig);
+        int paren = signature.lastIndexOf(')');
+        if (paren < 0) {
+            // Uncompilable snippet, punt with user parameter types
+            qpt = msi.parameterTypes();
+        } else {
+            qpt = signature.substring(0, paren + 1);
+        }
+        return qpt;
+    }
+
+    SnippetEvent event(String value, Exception exception) {
+        boolean wasSignatureChanged = sigChanged();
+        state.debug(DBG_EVNT, "Snippet: %s id: %s before: %s status: %s sig: %b cause: %s\n",
+                si, si.id(), prevStatus, si.status(), wasSignatureChanged, causalSnippet);
+        return new SnippetEvent(si, prevStatus, si.status(),
+                wasSignatureChanged, causalSnippet, value, exception);
+    }
+
+    List<SnippetEvent> secondaryEvents() {
+        return secondaryEvents;
+    }
+
+    @Override
+    public String toString() {
+        return "Unit(" + si.name() + ")";
+    }
+
+    /**
+     * Separate out the unresolvedDependencies errors from both the other
+     * corralling errors and the overall errors.
+     */
+    private static class UnresolvedExtractor {
+
+        private static final String RESOLVE_ERROR_SYMBOL = "symbol:";
+        private static final String RESOLVE_ERROR_LOCATION = "location:";
+
+        //TODO extract from tree instead -- note: internationalization
+        private final Set<String> unresolved = new LinkedHashSet<>();
+        private final DiagList otherErrors = new DiagList();
+        private final DiagList otherAll = new DiagList();
+
+        UnresolvedExtractor(DiagList diags) {
+            for (Diag diag : diags) {
+                if (diag.isError()) {
+                    if (diag.isResolutionError()) {
+                        String m = diag.getMessage(null);
+                        int symPos = m.indexOf(RESOLVE_ERROR_SYMBOL);
+                        if (symPos >= 0) {
+                            m = m.substring(symPos + RESOLVE_ERROR_SYMBOL.length());
+                            int symLoc = m.indexOf(RESOLVE_ERROR_LOCATION);
+                            if (symLoc >= 0) {
+                                m = m.substring(0, symLoc);
+                            }
+                            m = m.trim();
+                            unresolved.add(m);
+                            continue;
+                        }
+                    }
+                    otherErrors.add(diag);
+                }
+                otherAll.add(diag);
+            }
+        }
+
+        DiagList otherCorralledErrors() {
+            return otherErrors;
+        }
+
+        DiagList otherAll() {
+            return otherAll;
+        }
+
+        List<String> unresolved() {
+            return new ArrayList<>(unresolved);
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java
new file mode 100644
index 0000000..eaf240d
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+/**
+ * Exception reported on attempting to execute a
+ * {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED}
+ * method.
+ * <p>
+ * The stack can be queried by methods on <code>Exception</code>.
+ * Note that in stack trace frames representing JShell Snippets,
+ * <code>StackTraceElement.getFileName()</code> will return "#" followed by
+ * the Snippet id and for snippets without a method name (for example an
+ * expression) <code>StackTraceElement.getMethodName()</code> will be the
+ * empty string.
+ */
+@SuppressWarnings("serial")             // serialVersionUID intentionally omitted
+public class UnresolvedReferenceException extends Exception {
+
+    final MethodSnippet methodSnippet;
+
+    UnresolvedReferenceException(MethodSnippet methodSnippet, StackTraceElement[] stackElements) {
+        super("Attempt to invoke method with unresolved references");
+        this.methodSnippet = methodSnippet;
+        this.setStackTrace(stackElements);
+    }
+
+    /**
+     * Return the method Snippet which has the unresolved reference(s).
+     * @return the <code>MethodSnippet</code> of the
+     * {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED}
+     * method.
+     */
+    public MethodSnippet getMethodSnippet() {
+        return methodSnippet;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java
new file mode 100644
index 0000000..c41c04f
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java
@@ -0,0 +1,94 @@
+ /*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jshell;
+
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.lang.model.element.Name;
+import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
+import static jdk.internal.jshell.remote.RemoteCodes.prefixPattern;
+
+/**
+ * Assorted shared utilities.
+ * @author Robert Field
+ */
+class Util {
+
+    static final String REPL_CLASS_PREFIX = "$REPL";
+    static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"00DOESNOTMATTER";
+
+    static boolean isDoIt(Name name) {
+        return isDoIt(name.toString());
+    }
+
+    static boolean isDoIt(String sname) {
+        return sname.equals(DOIT_METHOD_NAME);
+    }
+
+    static String expunge(String s) {
+        StringBuilder sb = new StringBuilder();
+        for (String comp : prefixPattern.split(s)) {
+            sb.append(comp);
+        }
+        return sb.toString();
+    }
+
+    static String asLetters(int i) {
+        if (i == 0) {
+            return "";
+        }
+
+        char buf[] = new char[33];
+        int charPos = 32;
+
+        i = -i;
+        while (i <= -26) {
+            buf[charPos--] = (char) ('A'-(i % 26));
+            i = i / 26;
+        }
+        buf[charPos] = (char) ('A'-i);
+
+        return new String(buf, charPos, (33 - charPos));
+    }
+
+
+    static String trimEnd(String s) {
+        int last = s.length() - 1;
+        int i = last;
+        while (i >= 0 && Character.isWhitespace(s.charAt(i))) {
+            --i;
+        }
+        if (i != last) {
+            return s.substring(0, i + 1);
+        } else {
+            return s;
+        }
+    }
+
+    static <T> Stream<T> stream(Iterable<T> iterable) {
+        return StreamSupport.stream(iterable.spliterator(), false);
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java
new file mode 100644
index 0000000..8b93fab
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.Collection;
+import jdk.jshell.Key.VarKey;
+
+/**
+ * Snippet for a variable definition.
+ * The Kind is {@link jdk.jshell.Snippet.Kind#VAR}.
+ * <p>
+ * <code>VarSnippet</code> is immutable: an access to
+ * any of its methods will always return the same result.
+ * and thus is thread-safe.
+ * @jls 8.3: FieldDeclaration.
+ */
+public class VarSnippet extends DeclarationSnippet {
+
+    final String typeName;
+
+     VarSnippet(VarKey key, String userSource, Wrap guts,
+            String name, SubKind subkind, String typeName,
+            Collection<String> declareReferences) {
+        super(key, userSource, guts, name, subkind, null, declareReferences, null);
+        this.typeName = typeName;
+    }
+
+    /**
+     * A String representation of the type of the variable.
+     * @return the variable type as a String.
+     */
+    public String typeName() {
+        return typeName;
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java
new file mode 100644
index 0000000..aba8051
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Wrap.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jshell;
+
+import java.util.ArrayList;
+import java.util.List;
+import static jdk.internal.jshell.remote.RemoteCodes.DOIT_METHOD_NAME;
+
+/**
+ * Wrapping of source into Java methods, fields, etc.  All but outer layer
+ * wrapping with imports and class.
+ *
+ * @author Robert Field
+ */
+abstract class Wrap implements GeneralWrap {
+
+    private static Wrap methodWrap(String prefix, String source, String suffix) {
+        Wrap wunit = new NoWrap(source);
+        return new DoitMethodWrap(new CompoundWrap(prefix, wunit, suffix));
+    }
+
+    public static Wrap methodWrap(String source) {
+        return methodWrap("", source, semi(source) + "        return null;\n");
+    }
+
+    public static Wrap methodReturnWrap(String source) {
+        return methodWrap("return ", source, semi(source));
+    }
+
+    public static Wrap methodUnreachableSemiWrap(String source) {
+        return methodWrap("", source, semi(source));
+    }
+
+    public static Wrap methodUnreachableWrap(String source) {
+        return methodWrap("", source, "");
+    }
+
+    public static Wrap corralledMethod(String source, Range modRange, Range tpRange, Range typeRange, String name, Range paramRange, Range throwsRange, int id) {
+        List<Object> l = new ArrayList<>();
+        l.add("    public static\n    ");
+        if (!modRange.isEmpty()) {
+            l.add(new RangeWrap(source, modRange));
+            l.add(" ");
+        }
+        if (tpRange != null) {
+            l.add("<");
+            l.add(new RangeWrap(source, tpRange));
+            l.add("> ");
+        }
+        l.add(new RangeWrap(source, typeRange));
+        l.add(" " + name + "(\n        ");
+        if (paramRange != null) {
+            l.add(new RangeWrap(source, paramRange));
+        }
+        l.add(") ");
+        if (throwsRange != null) {
+            l.add("throws ");
+            l.add(new RangeWrap(source, throwsRange));
+        }
+        l.add(" {\n        throw new jdk.internal.jshell.remote.RemoteResolutionException(" + id + ");\n}\n");
+        return new CompoundWrap(l.toArray());
+    }
+
+    /**
+     *
+     * @param in
+     * @param rname
+     * @param rinit Initializer or null
+     * @param rdecl Type name and name
+     * @return
+     */
+    public static Wrap varWrap(String source, Range rtype, String brackets, Range rname, Range rinit) {
+        RangeWrap wname = new RangeWrap(source, rname);
+        RangeWrap wtype = new RangeWrap(source, rtype);
+        Wrap wVarDecl = new VarDeclareWrap(wtype, brackets, wname);
+        Wrap wmeth;
+
+        if (rinit == null) {
+            wmeth = new CompoundWrap(new NoWrap(" "), "   return null;\n");
+        } else {
+            RangeWrap winit = new RangeWrap(source, rinit);
+        // int x = y
+            // int x_ = y; return x = x_;
+            // decl + "_ = " + init ; + "return " + name + "=" + name + "_ ;"
+            wmeth = new CompoundWrap(
+                    wtype, brackets + " ", wname, "_ =\n        ", winit, semi(winit),
+                    "        return ", wname, " = ", wname, "_;\n"
+            );
+        }
+        Wrap wInitMeth = new DoitMethodWrap(wmeth);
+        return new CompoundWrap(wVarDecl, wInitMeth);
+    }
+
+    public static Wrap tempVarWrap(String source, String typename, String name) {
+        RangeWrap winit = new NoWrap(source);
+        // y
+        // return $1 = y;
+        // "return " + $1 + "=" + init ;
+        Wrap wmeth = new CompoundWrap("return " + name + " =\n        ", winit, semi(winit));
+        Wrap wInitMeth = new DoitMethodWrap(wmeth);
+
+        String varDecl = "    public static\n    " + typename + " " + name + ";\n";
+        return new CompoundWrap(varDecl, wInitMeth);
+    }
+
+    public static Wrap importWrap(String source) {
+        return new NoWrap(source);
+    }
+
+    public static Wrap classMemberWrap(String source) {
+        Wrap w = new NoWrap(source);
+        return new CompoundWrap("    public static\n    ", w);
+    }
+
+    private static int countLines(String s) {
+        return countLines(s, 0, s.length());
+    }
+
+    private static int countLines(String s, int from, int toEx) {
+        int cnt = 0;
+        int idx = from;
+        while ((idx = s.indexOf('\n', idx)) > 0) {
+            if (idx >= toEx) break;
+            ++cnt;
+            ++idx;
+        }
+        return cnt;
+    }
+
+    public static final class Range {
+        final int begin;
+        final int end;
+
+        Range(int begin, int end) {
+            this.begin = begin;
+            this.end = end;
+        }
+
+        Range(String s) {
+            this.begin = 0;
+            this.end = s.length();
+        }
+
+        String part(String s) {
+            return s.substring(begin, end);
+        }
+
+        int length() {
+            return end - begin;
+        }
+
+        boolean isEmpty() {
+            return end == begin;
+        }
+
+        void verify(String s) {
+            if (begin < 0 || end <= begin || end > s.length()) {
+                throw new InternalError("Bad Range: " + s + "[" + begin + "," + end + "]");
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "Range[" + begin + "," + end + "]";
+        }
+    }
+
+    public static class CompoundWrap extends Wrap {
+
+        final Object[] os;
+        final String wrapped;
+        final int snidxFirst;
+        final int snidxLast;
+        final int snlineFirst;
+        final int snlineLast;
+
+        CompoundWrap(Object... os) {
+            this.os = os;
+            int sniFirst = Integer.MAX_VALUE;
+            int sniLast = Integer.MIN_VALUE;
+            int snlnFirst = Integer.MAX_VALUE;
+            int snlnLast = Integer.MIN_VALUE;
+            StringBuilder sb = new StringBuilder();
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    sb.append(s);
+                } else if (o instanceof Wrap) {
+                    Wrap w = (Wrap) o;
+                    if (w.firstSnippetIndex() < sniFirst) {
+                        sniFirst = w.firstSnippetIndex();
+                    }
+                    if (w.lastSnippetIndex() > sniLast) {
+                        sniLast = w.lastSnippetIndex();
+                    }
+                    if (w.firstSnippetLine() < snlnFirst) {
+                        snlnFirst = w.firstSnippetLine();
+                    }
+                    if (w.lastSnippetLine() > snlnLast) {
+                        snlnLast = w.lastSnippetLine();
+                    }
+                    sb.append(w.wrapped());
+                } else {
+                    throw new InternalError("Bad object in CommoundWrap: " + o);
+                }
+            }
+            this.wrapped = sb.toString();
+            this.snidxFirst = sniFirst;
+            this.snidxLast = sniLast;
+            this.snlineFirst = snlnFirst;
+            this.snlineLast = snlnLast;
+        }
+
+        @Override
+        public String wrapped() {
+            return wrapped;
+        }
+
+        @Override
+        public int snippetIndexToWrapIndex(int sni) {
+            int before = 0;
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    before += s.length();
+                } else if (o instanceof Wrap) {
+                    Wrap w = (Wrap) o;
+                    if (sni >= w.firstSnippetIndex() && sni <= w.lastSnippetIndex()) {
+                        return w.snippetIndexToWrapIndex(sni) + before;
+                    }
+                    before += w.wrapped().length();
+                }
+            }
+            return 0;
+        }
+
+        @Override
+        public int wrapIndexToSnippetIndex(int wi) {
+            int before = 0;
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    before += s.length();
+                } else if (o instanceof Wrap) {
+                    Wrap w = (Wrap) o;
+                    int len = w.wrapped().length();
+                    if ((wi - before) <= len) {
+                        //System.err.printf("Defer to wrap %s - wi: %d. before; %d   -- %s  >>> %s\n",
+                        //        w, wi, before, w.debugPos(wi - before), w.wrapped());
+                        return w.wrapIndexToSnippetIndex(wi - before);
+                    }
+                    before += len;
+                }
+            }
+            return lastSnippetIndex();
+        }
+
+        @Override
+        public int firstSnippetIndex() {
+            return snidxFirst;
+        }
+
+        @Override
+        public int lastSnippetIndex() {
+            return snidxLast;
+        }
+
+        @Override
+        public int snippetLineToWrapLine(int snline) {
+            int before = 0;
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    before += countLines(s);
+                } else if (o instanceof Wrap) {
+                    Wrap w = (Wrap) o;
+                    if (snline >= w.firstSnippetLine() && snline <= w.lastSnippetLine()) {
+                        return w.snippetLineToWrapLine(snline) + before;
+                    }
+                    before += countLines(w.wrapped());
+                }
+            }
+            return 0;
+        }
+
+        @Override
+        public int wrapLineToSnippetLine(int wline) {
+            int before = 0;
+            for (Object o : os) {
+                if (o instanceof String) {
+                    String s = (String) o;
+                    before += countLines(s);
+                } else if (o instanceof Wrap) {
+                    Wrap w = (Wrap) o;
+                    int lns = countLines(w.wrapped());
+                    if ((wline - before) < lns) {
+                        return w.wrapLineToSnippetLine(wline - before);
+                    }
+                    before += lns;
+                }
+            }
+            return 0;
+        }
+
+        @Override
+        public int firstSnippetLine() {
+            return snlineFirst;
+        }
+
+        @Override
+        public int lastSnippetLine() {
+            return snlineLast;
+        }
+
+
+    }
+
+    private static class RangeWrap extends Wrap {
+
+        final Range range;
+        final String wrapped;
+        final int firstSnline;
+        final int lastSnline;
+
+        RangeWrap(String snippetSource, Range usedWithinSnippet) {
+            this.range = usedWithinSnippet;
+            this.wrapped = usedWithinSnippet.part(snippetSource);
+            usedWithinSnippet.verify(snippetSource);
+            this.firstSnline = countLines(snippetSource, 0, range.begin);
+            this.lastSnline = firstSnline + countLines(snippetSource, range.begin, range.end);
+        }
+
+        @Override
+        public String wrapped() {
+            return wrapped;
+        }
+
+        @Override
+        public int snippetIndexToWrapIndex(int sni) {
+            if (sni < range.begin) {
+                return 0;
+            }
+            if (sni > range.end) {
+                return range.length();
+            }
+            return sni - range.begin;
+        }
+
+        @Override
+        public int wrapIndexToSnippetIndex(int wi) {
+            if (wi < 0) {
+                return 0; // bad index
+            }
+            int max = range.length();
+            if (wi > max) {
+                wi = max;
+            }
+            return wi + range.begin;
+        }
+
+        @Override
+        public int firstSnippetIndex() {
+            return range.begin;
+        }
+
+        @Override
+        public int lastSnippetIndex() {
+            return range.end;
+        }
+
+        @Override
+        public int snippetLineToWrapLine(int snline) {
+            if (snline < firstSnline) {
+                return 0;
+            }
+            if (snline >= lastSnline) {
+                return lastSnline - firstSnline;
+            }
+            return snline - firstSnline;
+        }
+
+        @Override
+        public int wrapLineToSnippetLine(int wline) {
+            if (wline < 0) {
+                return 0; // bad index
+            }
+            int max = lastSnline - firstSnline;
+            if (wline > max) {
+                wline = max;
+            }
+            return wline + firstSnline;
+        }
+
+        @Override
+        public int firstSnippetLine() {
+            return firstSnline;
+        }
+
+        @Override
+        public int lastSnippetLine() {
+            return lastSnline;
+        }
+
+    }
+
+    private static class NoWrap extends RangeWrap {
+
+        NoWrap(String unit) {
+            super(unit, new Range(unit));
+        }
+    }
+
+    private static String semi(Wrap w) {
+        return semi(w.wrapped());
+    }
+
+    private static String semi(String s) {
+        return ((s.endsWith(";")) ? "\n" : ((s.endsWith(";\n")) ? "" : ";\n"));
+    }
+
+    private static class DoitMethodWrap extends CompoundWrap {
+
+        DoitMethodWrap(Wrap w) {
+            super("    public static Object " + DOIT_METHOD_NAME + "() throws Throwable {\n"
+                    + "        ", w,
+                    "    }\n");
+        }
+    }
+
+    private static class VarDeclareWrap extends CompoundWrap {
+
+        VarDeclareWrap(Wrap wtype, String brackets, Wrap wname) {
+            super("    public static ", wtype, brackets + " ", wname, semi(wname));
+        }
+    }
+}
diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java
new file mode 100644
index 0000000..5d9df00
--- /dev/null
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+/**
+ * Provides interfaces for creating tools, such as a Read-Eval-Print Loop (REPL),
+ * which interactively evaluate "snippets" of Java programming language code.
+ * Where a "snippet" is a single expression, statement, or declaration.
+ * This functionality can be used to enhance tools such as IDEs or can be
+ * stand-alone.
+ * <p>
+ * {@link jdk.jshell.JShell} is the central class.  An instance of
+ * <code>JShell</code> holds the evaluation state, which is both the current
+ * set of source snippets and the execution state they have produced.
+ * <p>
+ * Each source snippet is represented by an instance of a subclass of
+ * {@link jdk.jshell.Snippet}. For example, a statement is represented by an
+ * instance of {@link jdk.jshell.StatementSnippet}, and a method declaration is
+ * represented by an instance of {@link jdk.jshell.MethodSnippet}.
+ * Snippets are created when {@link jdk.jshell.JShell#eval(java.lang.String)}
+ * is invoked with an input which includes one or more snippets of code.
+ * <p>
+ * Any change to the compilation status of a snippet is reported with a
+ * {@link jdk.jshell.SnippetEvent}.  There are three major kinds of
+ * changes to the status of a snippet: it can created with <code>eval</code>,
+ * it can be dropped from the active source state with
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet)}, and it can have
+ * its status updated as a result of a status change in another snippet.
+ * For
+ * example: given <code>js</code>, an instance of <code>JShell</code>, executing
+ * <code>js.eval("int x = 5;")</code> will add the variable <code>x</code> to
+ * the source state and will generate an event describing the creation of a
+ * {@link jdk.jshell.VarSnippet} for <code>x</code>. Then executing
+ * <code>js.eval("int timesx(int val) { return val * x; }")</code> will add
+ * a method to the source state and will generate an event
+ * describing the creation of a {@link jdk.jshell.MethodSnippet} for
+ * <code>timesx</code>.
+ * Assume that <code>varx</code> holds the snippet created by the first
+ * call to <code>eval</code>, executing <code>js.drop(varx)</code> will
+ * generate two events: one for changing the status of the
+ * variable snippet to <code>DROPPED</code> and one for
+ * updating the method snippet (which now has an unresolved reference to
+ * <code>x</code>).
+ * <p>
+ * Of course, for any general application of the API, the input would not be
+ * fixed strings, but would come from the user. Below is a very simplified
+ * example of how the API might be used to implement a REPL.
+ * <pre>
+* {@code
+ *     import java.io.ByteArrayInputStream;
+ *     import java.io.Console;
+ *     import java.util.List;
+ *     import jdk.jshell.*;
+ *     import jdk.jshell.Snippet.Status;
+ *
+ *     class ExampleJShell {
+ *         public static void main(String[] args) {
+ *             Console console = System.console();
+ *             try (JShell js = JShell.create()) {
+ *                 do {
+ *                     System.out.print("Enter some Java code: ");
+ *                     String input = console.readLine();
+ *                     if (input == null) {
+ *                         break;
+ *                     }
+ *                     List&lt;SnippetEvent&gt; events = js.eval(input);
+ *                     for (SnippetEvent e : events) {
+ *                         StringBuilder sb = new StringBuilder();
+ *                         if (e.causeSnippet == null) {
+ *                             //  We have a snippet creation event
+ *                             switch (e.status) {
+ *                                 case VALID:
+ *                                     sb.append("Successful ");
+ *                                     break;
+ *                                 case RECOVERABLE_DEFINED:
+ *                                     sb.append("With unresolved references ");
+ *                                     break;
+ *                                 case RECOVERABLE_NOT_DEFINED:
+ *                                     sb.append("Possibly reparable, failed  ");
+ *                                     break;
+ *                                 case REJECTED:
+ *                                     sb.append("Failed ");
+ *                                     break;
+ *                             }
+ *                             if (e.previousStatus == Status.NONEXISTENT) {
+ *                                 sb.append("addition");
+ *                             } else {
+ *                                 sb.append("modification");
+ *                             }
+ *                             sb.append(" of ");
+ *                             sb.append(e.snippet.source());
+ *                             System.out.println(sb);
+ *                             if (e.value != null) {
+ *                                 System.out.printf("Value is: %s\n", e.value);
+ *                             }
+ *                             System.out.flush();
+ *                         }
+ *                     }
+ *                 } while (true);
+ *             }
+ *             System.out.println("\nGoodbye");
+ *         }
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * To register for status change events use
+ * {@link jdk.jshell.JShell#onSnippetEvent(java.util.function.Consumer)}.
+ * These events are only generated by <code>eval</code> and <code>drop</code>,
+ * the return values of these methods are the list of events generated by that
+ * call.  So, as in the example above, events can be used without registering
+ * to receive events.
+ * <p>
+ * If you experiment with this example, you will see that failing to terminate
+ * a statement or variable declaration with a semi-colon will simply fail.
+ * An unfinished entry (for example a desired multi-line method) will also just
+ * fail after one line.  The utilities in {@link jdk.jshell.SourceCodeAnalysis}
+ * provide source boundary and completeness analysis to address cases like
+ * those.  <code>SourceCodeAnalysis</code> also provides suggested completions
+ * of input, as might be used in tab-completion.
+ */
+
+
+package jdk.jshell;
+
diff --git a/langtools/test/com/sun/javadoc/testSimpleTag/TestSimpleTag.java b/langtools/test/com/sun/javadoc/testSimpleTag/TestSimpleTag.java
index 890f50f..d452dbc 100644
--- a/langtools/test/com/sun/javadoc/testSimpleTag/TestSimpleTag.java
+++ b/langtools/test/com/sun/javadoc/testSimpleTag/TestSimpleTag.java
@@ -51,7 +51,8 @@
                 "-tag", "regular:a:Regular Tag:",
                 "-tag", "back-slash\\:tag\\\\:a:Back-Slash-Tag:",
                 testSrc("C.java"));
-        checkExit(Exit.FAILED); // TODO: investigate why failed
+        // doclint fails because '\' is not allowed in tag name
+        checkExit(Exit.FAILED);
 
         checkOutput("C.html", true,
                 "<span class=\"simpleTagLabel\">Todo:</span>",
diff --git a/langtools/test/jdk/jshell/AnalysisTest.java b/langtools/test/jdk/jshell/AnalysisTest.java
new file mode 100644
index 0000000..f6cd5bf
--- /dev/null
+++ b/langtools/test/jdk/jshell/AnalysisTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 SourceCodeAnalysis
+ * @build KullaTesting TestingInputStream
+ * @run testng AnalysisTest
+ */
+
+import org.testng.annotations.Test;
+
+@Test
+public class AnalysisTest extends KullaTesting {
+
+    public void testSource() {
+        assertAnalyze("int x=3//test", "int x=3;//test", "", true);
+        assertAnalyze("int x=3 ;//test", "int x=3 ;//test", "", true);
+        assertAnalyze("int x=3 //;", "int x=3; //;", "", true);
+        assertAnalyze("void m5() {} /// hgjghj", "void m5() {} /// hgjghj", "", true);
+        assertAnalyze("int ff; int v // hi", "int ff;", " int v // hi", true);
+    }
+
+    public void testSourceSlashStar() {
+        assertAnalyze("/*zoo*/int x=3 /*test*/", "/*zoo*/int x=3; /*test*/", "", true);
+        assertAnalyze("/*zoo*/int x=3 ;/*test*/", "/*zoo*/int x=3 ;/*test*/", "", true);
+        assertAnalyze("int x=3 /*;*/", "int x=3; /*;*/", "", true);
+        assertAnalyze("void m5() {} /*hgjghj*/", "void m5() {} /*hgjghj*/", "", true);
+        assertAnalyze("int ff; int v /*hgjghj*/", "int ff;", " int v /*hgjghj*/", true);
+    }
+
+    public void testIncomplete() {
+        assertAnalyze("void m() { //erer", null, "void m() { //erer\n", false);
+        assertAnalyze("int m=//", null, "int m=//\n", false);
+    }
+
+    public void testExpression() {
+        assertAnalyze("45//test", "45//test", "", true);
+        assertAnalyze("45;//test", "45;//test", "", true);
+        assertAnalyze("45//;", "45//;", "", true);
+        assertAnalyze("/*zoo*/45/*test*/", "/*zoo*/45/*test*/", "", true);
+        assertAnalyze("/*zoo*/45;/*test*/", "/*zoo*/45;/*test*/", "", true);
+        assertAnalyze("45/*;*/", "45/*;*/", "", true);
+    }
+}
diff --git a/langtools/test/jdk/jshell/ClassMembersTest.java b/langtools/test/jdk/jshell/ClassMembersTest.java
new file mode 100644
index 0000000..ce5a758
--- /dev/null
+++ b/langtools/test/jdk/jshell/ClassMembersTest.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 access to members of user defined class.
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic
+ * @run testng/timeout=600 ClassMembersTest
+ */
+
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.SourceCodeAnalysis;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class ClassMembersTest extends KullaTesting {
+
+    @Test(dataProvider = "memberTestCase")
+    public void memberTest(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember, Static isStaticReference) {
+        MemberTestCase testCase = new MemberTestCase(accessModifier, codeChunk, isStaticMember, isStaticReference);
+        assertEval(testCase.generateSource());
+        String expectedMessage = testCase.expectedMessage;
+        if (testCase.codeChunk != CodeChunk.CONSTRUCTOR || testCase.isAccessible()) {
+            assertEval("A a = new A();");
+        }
+        if (expectedMessage == null) {
+            assertEval(testCase.useCodeChunk());
+        } else {
+            assertDeclareFail(testCase.useCodeChunk(), expectedMessage);
+        }
+    }
+
+    private List<String> parseCode(String input) {
+        List<String> list = new ArrayList<>();
+        SourceCodeAnalysis codeAnalysis = getAnalysis();
+        String source = input;
+        while (!source.trim().isEmpty()) {
+            SourceCodeAnalysis.CompletionInfo info = codeAnalysis.analyzeCompletion(source);
+            list.add(info.source);
+            source = info.remaining;
+        }
+        return list;
+    }
+
+    @Test(dataProvider = "memberTestCase")
+    public void extendsMemberTest(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember, Static isStaticReference) {
+        MemberTestCase testCase = new ExtendsMemberTestCase(accessModifier, codeChunk, isStaticMember, isStaticReference);
+        String input = testCase.generateSource();
+        List<String> ss = parseCode(input);
+        assertEval(ss.get(0));
+        if (testCase.codeChunk != CodeChunk.CONSTRUCTOR || testCase.isAccessible()) {
+            assertEval(ss.get(1));
+            assertEval("B b = new B();");
+        }
+        String expectedMessage = testCase.expectedMessage;
+        if (expectedMessage == null) {
+            assertEval(testCase.useCodeChunk());
+        } else {
+            assertDeclareFail(testCase.useCodeChunk(), expectedMessage);
+        }
+    }
+
+    @Test
+    public void interfaceTest() {
+        String interfaceSource =
+                "interface A {\n" +
+                "   default int defaultMethod() { return 1; }\n" +
+                "   static int staticMethod() { return 2; }\n" +
+                "   int method();\n" +
+                "   class Inner1 {}\n" +
+                "   static class Inner2 {}\n" +
+                "}";
+        assertEval(interfaceSource);
+        assertEval("A.staticMethod();", "2");
+        String classSource =
+                "class B implements A {\n" +
+                "   public int method() { return 3; }\n" +
+                "}";
+        assertEval(classSource);
+        assertEval("B b = new B();");
+        assertEval("b.defaultMethod();", "1");
+        assertDeclareFail("B.staticMethod();",
+                new ExpectedDiagnostic("compiler.err.cant.resolve.location.args", 0, 14, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertEval("b.method();", "3");
+        assertEval("new A.Inner1();");
+        assertEval("new A.Inner2();");
+        assertEval("new B.Inner1();");
+        assertEval("new B.Inner2();");
+    }
+
+    @Test
+    public void enumTest() {
+        String enumSource =
+                "enum E {A(\"s\");\n" +
+                "   private final String s;\n" +
+                "   private E(String s) { this.s = s; }\n" +
+                "   public String method() { return s; }\n" +
+                "   private String privateMethod() { return s; }\n" +
+                "   public static String staticMethod() { return staticPrivateMethod(); }\n" +
+                "   private static String staticPrivateMethod() { return \"a\"; }\n" +
+                "}";
+        assertEval(enumSource);
+        assertEval("E a = E.A;", "A");
+        assertDeclareFail("a.s;",
+                new ExpectedDiagnostic("compiler.err.report.access", 0, 3, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertDeclareFail("new E(\"q\");",
+                new ExpectedDiagnostic("compiler.err.enum.cant.be.instantiated", 0, 10, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertEval("a.method();", "\"s\"");
+        assertDeclareFail("a.privateMethod();",
+                new ExpectedDiagnostic("compiler.err.report.access", 0, 15, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertEval("E.staticMethod();", "\"a\"");
+        assertDeclareFail("a.staticPrivateMethod();",
+                new ExpectedDiagnostic("compiler.err.report.access", 0, 21, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertDeclareFail("E.method();",
+                new ExpectedDiagnostic("compiler.err.non-static.cant.be.ref", 0, 8, 1, -1, -1, Diagnostic.Kind.ERROR));
+    }
+
+    @Test(enabled = false) // TODO 8080354
+    public void annotationTest() {
+        assertEval("import java.lang.annotation.*;");
+        for (RetentionPolicy policy : RetentionPolicy.values()) {
+            String annotationSource =
+                    "@Retention(RetentionPolicy." + policy.toString() + ")\n" +
+                    "@interface A {}";
+            assertEval(annotationSource);
+            String classSource =
+                    "@A class C {\n" +
+                    "   @A C() {}\n" +
+                    "   @A void f() {}\n" +
+                    "   @A int f;\n" +
+                    "   @A class Inner {}\n" +
+                    "}";
+            assertEval(classSource);
+            String isRuntimeVisible = policy == RetentionPolicy.RUNTIME ? "true" : "false";
+            assertEval("C.class.getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
+            assertEval("C.class.getDeclaredConstructor().getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
+            assertEval("C.class.getDeclaredMethod(\"f\").getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
+            assertEval("C.class.getDeclaredField(\"f\").getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
+            assertEval("C.Inner.class.getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
+        }
+    }
+
+    @DataProvider(name = "memberTestCase")
+    public Object[][] memberTestCaseGenerator() {
+        List<Object[]> list = new ArrayList<>();
+        for (AccessModifier accessModifier : AccessModifier.values()) {
+            for (Static isStaticMember : Static.values()) {
+                for (Static isStaticReference : Static.values()) {
+                    for (CodeChunk codeChunk : CodeChunk.values()) {
+                        if (codeChunk == CodeChunk.CONSTRUCTOR && isStaticMember == Static.STATIC) {
+                            continue;
+                        }
+                        list.add(new Object[]{ accessModifier, codeChunk, isStaticMember, isStaticReference });
+                    }
+                }
+            }
+        }
+        return list.toArray(new Object[list.size()][]);
+    }
+
+    public static class ExtendsMemberTestCase extends MemberTestCase {
+
+        public ExtendsMemberTestCase(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember, Static isStaticReference) {
+            super(accessModifier, codeChunk, isStaticMember, isStaticReference);
+        }
+
+        @Override
+        public String getSourceTemplate() {
+            return super.getSourceTemplate() + "\n"
+                    + "class B extends A {}";
+        }
+
+        @Override
+        public String errorMessage() {
+            if (!isAccessible()) {
+                if (codeChunk == CodeChunk.METHOD) {
+                    return "compiler.err.cant.resolve.location.args";
+                }
+                if (codeChunk == CodeChunk.CONSTRUCTOR) {
+                    return "compiler.err.cant.resolve.location";
+                }
+            }
+            return super.errorMessage();
+        }
+
+        @Override
+        public String useCodeChunk() {
+            return useCodeChunk("B");
+        }
+    }
+
+    public static class MemberTestCase {
+        public final AccessModifier accessModifier;
+        public final CodeChunk codeChunk;
+        public final Static isStaticMember;
+        public final Static isStaticReference;
+        public final String expectedMessage;
+
+        public MemberTestCase(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember,
+                              Static isStaticReference) {
+            this.accessModifier = accessModifier;
+            this.codeChunk = codeChunk;
+            this.isStaticMember = isStaticMember;
+            this.isStaticReference = isStaticReference;
+            this.expectedMessage = errorMessage();
+        }
+
+        public String getSourceTemplate() {
+            return  "class A {\n" +
+                    "    #MEMBER#\n" +
+                    "}";
+        }
+
+        public boolean isAccessible() {
+            return accessModifier != AccessModifier.PRIVATE;
+        }
+
+        public String errorMessage() {
+            if (!isAccessible()) {
+                return "compiler.err.report.access";
+            }
+            if (codeChunk == CodeChunk.INNER_INTERFACE) {
+                return "compiler.err.abstract.cant.be.instantiated";
+            }
+            if (isStaticMember == Static.STATIC) {
+                if (isStaticReference == Static.NO && codeChunk == CodeChunk.INNER_CLASS) {
+                    return "compiler.err.qualified.new.of.static.class";
+                }
+                return null;
+            }
+            if (isStaticReference == Static.STATIC) {
+                if (codeChunk == CodeChunk.CONSTRUCTOR) {
+                    return null;
+                }
+                if (codeChunk == CodeChunk.INNER_CLASS) {
+                    return "compiler.err.encl.class.required";
+                }
+                return "compiler.err.non-static.cant.be.ref";
+            }
+            return null;
+        }
+
+        public String generateSource() {
+            return getSourceTemplate().replace("#MEMBER#", codeChunk.generateSource(accessModifier, isStaticMember));
+        }
+
+        protected String useCodeChunk(String className) {
+            String name = className.toLowerCase();
+            switch (codeChunk) {
+                case CONSTRUCTOR:
+                    return String.format("new %s();", className);
+                case METHOD:
+                    if (isStaticReference == Static.STATIC) {
+                        return String.format("%s.method();", className);
+                    } else {
+                        return String.format("%s.method();", name);
+                    }
+                case FIELD:
+                    if (isStaticReference == Static.STATIC) {
+                        return String.format("%s.field;", className);
+                    } else {
+                        return String.format("%s.field;", name);
+                    }
+                case INNER_CLASS:
+                    if (isStaticReference == Static.STATIC) {
+                        return String.format("new %s.Inner();", className);
+                    } else {
+                        return String.format("%s.new Inner();", name);
+                    }
+                case INNER_INTERFACE:
+                    return String.format("new %s.Inner();", className);
+                default:
+                    throw new AssertionError("Unknown code chunk: " + this);
+            }
+        }
+
+        public String useCodeChunk() {
+            return useCodeChunk("A");
+        }
+    }
+
+    public enum AccessModifier {
+        PUBLIC("public"),
+        PROTECTED("protected"),
+        PACKAGE_PRIVATE(""),
+        PRIVATE("private");
+
+        private final String modifier;
+
+        AccessModifier(String modifier) {
+            this.modifier = modifier;
+        }
+
+        public String getModifier() {
+            return modifier;
+        }
+    }
+
+    public enum Static {
+        STATIC("static"), NO("");
+
+        private final String modifier;
+
+        Static(String modifier) {
+            this.modifier = modifier;
+        }
+
+        public String getModifier() {
+            return modifier;
+        }
+    }
+
+    public enum CodeChunk {
+        CONSTRUCTOR("#MODIFIER# A() {}"),
+        METHOD("#MODIFIER# int method() { return 10; }"),
+        FIELD("#MODIFIER# int field = 10;"),
+        INNER_CLASS("#MODIFIER# class Inner {}"),
+        INNER_INTERFACE("#MODIFIER# interface Inner {}");
+
+        private final String code;
+
+        CodeChunk(String code) {
+            this.code = code;
+        }
+
+        public String generateSource(AccessModifier accessModifier, Static isStatic) {
+            return code.replace("#MODIFIER#", accessModifier.getModifier() + " " + isStatic.getModifier());
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/ClassPathTest.java b/langtools/test/jdk/jshell/ClassPathTest.java
new file mode 100644
index 0000000..a1ed89f
--- /dev/null
+++ b/langtools/test/jdk/jshell/ClassPathTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for EvalState#addToClasspath
+ * @library /tools/lib
+ * @build KullaTesting TestingInputStream ToolBox Compiler
+ * @run testng ClassPathTest
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.testng.annotations.Test;
+
+@Test
+public class ClassPathTest extends KullaTesting {
+
+    private final Compiler compiler = new Compiler();
+    private final Path outDir = Paths.get("class_path_test");
+
+    public void testDirectory() {
+        compiler.compile(outDir, "package pkg; public class TestDirectory { }");
+        assertDeclareFail("import pkg.TestDirectory;", "compiler.err.doesnt.exist");
+        assertDeclareFail("new pkg.TestDirectory();", "compiler.err.doesnt.exist");
+        addToClasspath(compiler.getPath(outDir));
+        assertEval("new pkg.TestDirectory();");
+    }
+
+    public void testJar() {
+        compiler.compile(outDir, "package pkg; public class TestJar { }");
+        String jarName = "test.jar";
+        compiler.jar(outDir, jarName, "pkg/TestJar.class");
+        assertDeclareFail("import pkg.TestJar;", "compiler.err.doesnt.exist");
+        assertDeclareFail("new pkg.TestJar();", "compiler.err.doesnt.exist");
+        addToClasspath(compiler.getPath(outDir).resolve(jarName));
+        assertEval("new pkg.TestJar();");
+    }
+
+    public void testAmbiguousDirectory() {
+        Path p1 = outDir.resolve("dir1");
+        compiler.compile(p1,
+                "package p; public class TestAmbiguous {\n" +
+                "   public String toString() {\n" +
+                "       return \"first\";" +
+                "   }\n" +
+                "}");
+        addToClasspath(compiler.getPath(p1));
+        Path p2 = outDir.resolve("dir2");
+        compiler.compile(p2,
+                "package p; public class TestAmbiguous {\n" +
+                "   public String toString() {\n" +
+                "       return \"second\";" +
+                "   }\n" +
+                "}");
+        addToClasspath(compiler.getPath(p2));
+        assertEval("new p.TestAmbiguous();", "first");
+    }
+
+    public void testAmbiguousJar() {
+        Path p1 = outDir.resolve("dir1");
+        compiler.compile(p1,
+                "package p; public class TestAmbiguous {\n" +
+                "   public String toString() {\n" +
+                "       return \"first\";" +
+                "   }\n" +
+                "}");
+        String jarName = "test.jar";
+        compiler.jar(p1, jarName, "p/TestAmbiguous.class");
+        addToClasspath(compiler.getPath(p1.resolve(jarName)));
+        Path p2 = outDir.resolve("dir2");
+        compiler.compile(p2,
+                "package p; public class TestAmbiguous {\n" +
+                "   public String toString() {\n" +
+                "       return \"second\";" +
+                "   }\n" +
+                "}");
+        addToClasspath(compiler.getPath(p2));
+        assertEval("new p.TestAmbiguous();", "first");
+    }
+
+    public void testEmptyClassPath() {
+        addToClasspath("");
+        assertEval("new java.util.ArrayList<String>();");
+    }
+
+    public void testUnknown() {
+        addToClasspath(compiler.getPath(outDir.resolve("UNKNOWN")));
+        assertDeclareFail("new Unknown();", "compiler.err.cant.resolve.location");
+        addToClasspath(compiler.getPath(outDir.resolve("UNKNOWN.jar")));
+        assertDeclareFail("new Unknown();", "compiler.err.cant.resolve.location");
+    }
+}
diff --git a/langtools/test/jdk/jshell/ClassesTest.java b/langtools/test/jdk/jshell/ClassesTest.java
new file mode 100644
index 0000000..1da6070
--- /dev/null
+++ b/langtools/test/jdk/jshell/ClassesTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for EvaluationState.classes
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic
+ * @run testng ClassesTest
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Snippet;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.VarSnippet;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jdk.jshell.Diag;
+import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
+import static jdk.jshell.Snippet.Status.DROPPED;
+import static jdk.jshell.Snippet.Status.REJECTED;
+import static jdk.jshell.Snippet.SubKind.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+
+@Test
+public class ClassesTest extends KullaTesting {
+
+    public void noClasses() {
+        assertNumberOfActiveClasses(0);
+    }
+
+    public void testSignature1() {
+        TypeDeclSnippet c1 = classKey(assertEval("class A extends B {}", added(RECOVERABLE_NOT_DEFINED)));
+        assertTypeDeclSnippet(c1, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0);
+        TypeDeclSnippet c2 = classKey(assertEval("@interface A { Class<B> f() default B.class; }",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(c1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertTypeDeclSnippet(c2, "A", RECOVERABLE_NOT_DEFINED, ANNOTATION_TYPE_SUBKIND, 1, 0);
+        TypeDeclSnippet c3 = classKey(assertEval("enum A {; private A(B b) {} }",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(c2, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertTypeDeclSnippet(c3, "A", RECOVERABLE_NOT_DEFINED, ENUM_SUBKIND, 1, 0);
+        TypeDeclSnippet c4 = classKey(assertEval("interface A extends B {}",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(c3, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertTypeDeclSnippet(c4, "A", RECOVERABLE_NOT_DEFINED, INTERFACE_SUBKIND, 1, 0);
+        TypeDeclSnippet c5 = classKey(assertEval("class A { void f(B b) {} }",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(c4, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertTypeDeclSnippet(c5, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0);
+    }
+
+    public void testSignature2() {
+        TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareFail("class A { void f() { return g(); } }", "compiler.err.prob.found.req");
+        assertTypeDeclSnippet(c1, "A", REJECTED, CLASS_SUBKIND, 0, 2);
+        TypeDeclSnippet c2 = classKey(assertEval("class A { int f() { return g(); } }",
+                ste(c1, REJECTED, RECOVERABLE_NOT_DEFINED, false, null)));
+        assertTypeDeclSnippet(c2, "A", RECOVERABLE_NOT_DEFINED, CLASS_SUBKIND, 1, 0);
+        assertDrop(c2,
+                ste(c2, RECOVERABLE_NOT_DEFINED, DROPPED, false, null));
+    }
+
+    public void classDeclaration() {
+        assertEval("class A { }");
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
+    }
+
+
+    public void interfaceDeclaration() {
+        assertEval("interface A { }");
+        assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"));
+    }
+
+    public void annotationDeclaration() {
+        assertEval("@interface A { }");
+        assertClasses(clazz(KullaTesting.ClassType.ANNOTATION, "A"));
+    }
+
+    public void enumDeclaration() {
+        assertEval("enum A { }");
+        assertClasses(clazz(KullaTesting.ClassType.ENUM, "A"));
+    }
+
+    public void classesDeclaration() {
+        assertEval("interface A { }");
+        assertEval("class B implements A { }");
+        assertEval("interface C extends A { }");
+        assertEval("enum D implements C { }");
+        assertEval("@interface E { }");
+        assertClasses(
+                clazz(KullaTesting.ClassType.INTERFACE, "A"),
+                clazz(KullaTesting.ClassType.CLASS, "B"),
+                clazz(KullaTesting.ClassType.INTERFACE, "C"),
+                clazz(KullaTesting.ClassType.ENUM, "D"),
+                clazz(KullaTesting.ClassType.ANNOTATION, "E"));
+        assertActiveKeys();
+    }
+
+    public void classesRedeclaration1() {
+        Snippet a = classKey(assertEval("class A { }"));
+        Snippet b = classKey(assertEval("interface B { }"));
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"), clazz(KullaTesting.ClassType.INTERFACE, "B"));
+        assertActiveKeys();
+
+        assertEval("interface A { }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"),
+                clazz(KullaTesting.ClassType.INTERFACE, "B"));
+        assertActiveKeys();
+
+        assertEval("interface B { } //again",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertClasses(clazz(KullaTesting.ClassType.INTERFACE, "A"),
+                clazz(KullaTesting.ClassType.INTERFACE, "B"));
+        assertActiveKeys();
+    }
+
+    public void classesRedeclaration2() {
+        assertEval("class A { }");
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"));
+        assertActiveKeys();
+
+        Snippet b = classKey(assertEval("class B extends A { }"));
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"),
+                clazz(KullaTesting.ClassType.CLASS, "B"));
+        assertActiveKeys();
+
+        Snippet c = classKey(assertEval("class C extends B { }"));
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"),
+                clazz(KullaTesting.ClassType.CLASS, "B"), clazz(KullaTesting.ClassType.CLASS, "C"));
+        assertActiveKeys();
+
+        assertEval("interface B { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(c, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "A"),
+                clazz(KullaTesting.ClassType.INTERFACE, "B"), clazz(KullaTesting.ClassType.CLASS, "C"));
+        assertEval("new C();",
+                DiagCheck.DIAG_ERROR,
+                DiagCheck.DIAG_ERROR,
+                added(REJECTED));
+        assertActiveKeys();
+    }
+
+    public void classesCyclic1() {
+        Snippet b = classKey(assertEval("class B extends A { }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        Snippet a = classKey(assertEval("class A extends B { }", DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE,
+                added(RECOVERABLE_NOT_DEFINED),
+                ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET)));
+        /***
+        assertDeclareFail("class A extends B { }", "****",
+                added(REJECTED),
+                ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET));
+        ***/
+        // It is random which one it shows up in, but cyclic error should be there
+        List<Diag> diagsA = getState().diagnostics(a);
+        List<Diag> diagsB = getState().diagnostics(b);
+        List<Diag> diags;
+        if (diagsA.isEmpty()) {
+            diags = diagsB;
+        } else {
+            diags = diagsA;
+            assertTrue(diagsB.isEmpty());
+        }
+        assertEquals(diags.size(), 1, "Expected one error");
+        assertEquals(diags.get(0).getCode(), "compiler.err.cyclic.inheritance", "Expected cyclic inheritance error");
+        assertActiveKeys();
+    }
+
+    public void classesCyclic2() {
+        Snippet d = classKey(assertEval("class D extends E { }", added(RECOVERABLE_NOT_DEFINED)));
+        assertEval("class E { D d; }",
+                added(VALID),
+                ste(d, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
+        assertActiveKeys();
+    }
+
+    public void classesCyclic3() {
+        Snippet outer = classKey(assertEval("class Outer { class Inner extends Foo { } }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        Snippet foo = classKey(assertEval("class Foo { } ",
+                added(VALID),
+                ste(outer, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)));
+        assertEval(" class Foo extends Outer { }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(foo, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(outer, VALID, VALID, true, MAIN_SNIPPET));
+        assertActiveKeys();
+    }
+
+    public void classesIgnoredModifiers() {
+        assertDeclareWarn1("public interface A { }",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING));
+        assertDeclareWarn1("static class B implements A { }",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING));
+        assertDeclareWarn1("final interface C extends A { }",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING));
+        assertDeclareWarn1("protected enum D implements C { }",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING));
+        assertActiveKeys();
+    }
+
+    public void ignoreModifierSpaceIssue() {
+        assertEval("interface I { void f(); } ");
+        // there should not be a space between 'I' and '{' to reproduce the failure
+        assertEval("class C implements I{ public void f() {}}");
+        assertClasses(clazz(KullaTesting.ClassType.CLASS, "C"), clazz(KullaTesting.ClassType.INTERFACE, "I"));
+        assertActiveKeys();
+    }
+
+    @DataProvider(name = "innerClasses")
+    public Object[][] innerClasses() {
+        List<Object[]> list = new ArrayList<>();
+        for (ClassType outerClassType : ClassType.values()) {
+            for (ClassType innerClassType : ClassType.values()) {
+                list.add(new Object[]{outerClassType, innerClassType});
+            }
+        }
+        return list.toArray(new Object[list.size()][]);
+    }
+
+    @Test(dataProvider = "innerClasses")
+    public void innerClasses(ClassType outerClassType, ClassType innerClassType) {
+        String source =
+                outerClassType + " A {" + (outerClassType == ClassType.ENUM ? ";" : "") +
+                innerClassType + " B { }" +
+                "}";
+        assertEval(source);
+        assertNumberOfActiveClasses(1);
+        assertActiveKeys();
+    }
+
+    public void testInnerClassesCrash() {
+        Snippet a = classKey(assertEval("class A { class B extends A {} }"));
+        Snippet a2 = classKey(assertEval("class A { interface I1 extends I2 {} interface I2 {} }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertEval("class A { A a = new A() {}; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+    }
+
+    public void testInnerClassesCrash1() {
+        assertEval("class A { class B extends A {} B getB() { return new B();} }");
+        assertEquals(varKey(assertEval("A a = new A();")).name(), "a");
+        VarSnippet variableKey = varKey(assertEval("a.getB();"));
+        assertEquals(variableKey.typeName(), "A.B");
+    }
+
+    public void testInnerClassesCrash2() {
+        assertEval("class A { interface I1 extends I2 {} interface I2 {} I1 x; }");
+        assertEquals(varKey(assertEval("A a = new A();")).name(), "a");
+        VarSnippet variableKey = varKey(assertEval("a.x;"));
+        assertEquals(variableKey.typeName(), "A.I1");
+    }
+}
diff --git a/langtools/test/jdk/jshell/CommandCompletionTest.java b/langtools/test/jdk/jshell/CommandCompletionTest.java
new file mode 100644
index 0000000..989caca
--- /dev/null
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Command Completion
+ * @library /tools/lib
+ * @build ReplToolTesting TestingInputStream Compiler ToolBox
+ * @run testng CommandCompletionTest
+ */
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.Test;
+
+@Test
+public class CommandCompletionTest extends ReplToolTesting {
+
+    public void testCommand() {
+        assertCompletion("/f|", false, "/feedback ");
+        assertCompletion("/deb|", false);
+        assertCompletion("/feedback v|", false, "verbose");
+        assertCompletion("/c|", false, "/classes ", "/classpath ");
+        assertCompletion("/h|", false, "/help ", "/history ");
+        assertCompletion("/feedback |", false,
+                "?", "concise", "default", "normal", "off", "verbose");
+    }
+
+    public void testList() {
+        assertCompletion("/l|", false, "/list ");
+        assertCompletion("/list |", false, "all");
+        assertCompletion("/list q|", false);
+    }
+
+    public void testDrop() {
+        assertCompletion("/d|", false, "/drop ");
+
+        test(false, new String[] {"-nostartup"},
+                a -> assertClass(a, "class cTest {}", "class", "cTest"),
+                a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
+                a -> assertVariable(a, "int", "fTest"),
+                a -> assertCompletion(a, "/drop |", false, "1", "2", "3", "cTest", "fTest", "mTest"),
+                a -> assertCompletion(a, "/drop f|", false, "fTest")
+        );
+    }
+
+    public void testEdit() {
+        assertCompletion("/e|", false, "/edit ", "/exit ");
+        assertCompletion("/ed|", false, "/edit ");
+
+        test(false, new String[]{"-nostartup"},
+                a -> assertClass(a, "class cTest {}", "class", "cTest"),
+                a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
+                a -> assertVariable(a, "int", "fTest"),
+                a -> assertCompletion(a, "/edit |", false, "1", "2", "3", "cTest", "fTest", "mTest"),
+                a -> assertCompletion(a, "/edit f|", false, "fTest")
+        );
+    }
+
+    public void testOpen() throws IOException {
+        Compiler compiler = new Compiler();
+        assertCompletion("/o|", false, "/open ");
+        List<String> p1 = listFiles(Paths.get(""));
+        FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
+        Collections.sort(p1);
+        assertCompletion("/open |", false, p1.toArray(new String[p1.size()]));
+        Path classDir = compiler.getClassDir();
+        List<String> p2 = listFiles(classDir);
+        assertCompletion("/open " + classDir + "/|", false, p2.toArray(new String[p2.size()]));
+    }
+
+    public void testSave() throws IOException {
+        Compiler compiler = new Compiler();
+        assertCompletion("/s|", false, "/save ", "/savestart ", "/seteditor ", "/setstart ");
+        List<String> p1 = listFiles(Paths.get(""));
+        Collections.addAll(p1, "all ", "history ");
+        FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
+        Collections.sort(p1);
+        assertCompletion("/save |", false, p1.toArray(new String[p1.size()]));
+        Path classDir = compiler.getClassDir();
+        List<String> p2 = listFiles(classDir);
+        assertCompletion("/save " + classDir + "/|",
+                false, p2.toArray(new String[p2.size()]));
+        assertCompletion("/save all " + classDir + "/|",
+                false, p2.toArray(new String[p2.size()]));
+    }
+
+    public void testClassPath() throws IOException {
+        assertCompletion("/classp|", false, "/classpath ");
+        Compiler compiler = new Compiler();
+        Path outDir = compiler.getPath("testClasspathCompletion");
+        Files.createDirectories(outDir);
+        Files.createDirectories(outDir.resolve("dir"));
+        createIfNeeded(outDir.resolve("test.jar"));
+        createIfNeeded(outDir.resolve("test.zip"));
+        compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
+        String jarName = "test.jar";
+        compiler.jar(outDir, jarName, "pkg/A.class");
+        compiler.getPath(outDir).resolve(jarName);
+        List<String> paths = listFiles(outDir, CLASSPATH_FILTER);
+        assertCompletion("/classpath " + outDir + "/|", false, paths.toArray(new String[paths.size()]));
+    }
+
+    public void testUserHome() throws IOException {
+        List<String> completions;
+        Path home = Paths.get(System.getProperty("user.home"));
+        try (Stream<Path> content = Files.list(home)) {
+            completions = content.filter(CLASSPATH_FILTER)
+                                 .map(file -> file.getFileName().toString() + (Files.isDirectory(file) ? "/" : ""))
+                                 .sorted()
+                                 .collect(Collectors.toList());
+        }
+        assertCompletion("/classpath ~/|", false, completions.toArray(new String[completions.size()]));
+    }
+
+    private void createIfNeeded(Path file) throws IOException {
+        if (!Files.exists(file))
+            Files.createFile(file);
+    }
+    private List<String> listFiles(Path path) throws IOException {
+        return listFiles(path, ACCEPT_ALL);
+    }
+
+    private List<String> listFiles(Path path, Predicate<? super Path> filter) throws IOException {
+        try (Stream<Path> stream = Files.list(path)) {
+            return stream.filter(filter)
+                         .map(p -> p.getFileName().toString() + (Files.isDirectory(p) ? "/" : ""))
+                         .sorted()
+                         .collect(Collectors.toList());
+        }
+    }
+
+    private static final Predicate<? super Path> ACCEPT_ALL =
+            (file) -> !file.endsWith(".") && !file.endsWith("..");
+
+    private static final Predicate<? super Path> CLASSPATH_FILTER =
+            (file) -> ACCEPT_ALL.test(file) &&
+                    (Files.isDirectory(file) ||
+                     file.getFileName().toString().endsWith(".jar") ||
+                     file.getFileName().toString().endsWith(".zip"));
+}
diff --git a/langtools/test/jdk/jshell/Compiler.java b/langtools/test/jdk/jshell/Compiler.java
new file mode 100644
index 0000000..fc3ff8a
--- /dev/null
+++ b/langtools/test/jdk/jshell/Compiler.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+public class Compiler {
+
+    private final ToolBox tb = new ToolBox();
+
+    public Path getClassDir() {
+        String classes = ToolBox.testClasses;
+        if (classes == null) {
+            return Paths.get("build");
+        } else {
+            return Paths.get(classes);
+        }
+    }
+
+    public Path getPath(String path) {
+        return getPath(Paths.get(path));
+    }
+
+    public Path getPath(Path path) {
+        return getClassDir().resolve(path);
+    }
+
+    public void compile(String...sources) {
+        compile(Paths.get("."), sources);
+    }
+
+    public void compile(Path directory, String...sources) {
+        Path classDir = getClassDir();
+        tb.new JavacTask()
+                .options("-d", classDir.resolve(directory).toString())
+                .sources(sources)
+                .run();
+    }
+
+    public void jar(String jarName, String...files) {
+        jar(Paths.get("."), jarName, files);
+    }
+
+    public void jar(Path directory, String jarName, String...files) {
+        Manifest manifest = new Manifest();
+        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
+        Path classDirPath = getClassDir();
+        Path baseDir = classDirPath.resolve(directory);
+        Path jarPath = baseDir.resolve(jarName);
+        tb.new JarTask(jarPath.toString())
+                .manifest(manifest)
+                .baseDir(baseDir.toString())
+                .files(files).run();
+    }
+
+    public void writeToFile(Path path, String...sources) {
+        try {
+            if (path.getParent() != null) {
+                Files.createDirectories(path.getParent());
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+        try (BufferedWriter writer = Files.newBufferedWriter(path)) {
+            for (String source : sources) {
+                writer.append(source);
+                writer.append('\n');
+            }
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/CompletenessStressTest.java b/langtools/test/jdk/jshell/CompletenessStressTest.java
new file mode 100644
index 0000000..1071487
--- /dev/null
+++ b/langtools/test/jdk/jshell/CompletenessStressTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.lang.model.element.Modifier;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.BreakTree;
+import com.sun.source.tree.CaseTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ContinueTree;
+import com.sun.source.tree.DoWhileLoopTree;
+import com.sun.source.tree.ExpressionStatementTree;
+import com.sun.source.tree.ForLoopTree;
+import com.sun.source.tree.IfTree;
+import com.sun.source.tree.ImportTree;
+import com.sun.source.tree.LabeledStatementTree;
+import com.sun.source.tree.LineMap;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.ReturnTree;
+import com.sun.source.tree.StatementTree;
+import com.sun.source.tree.SwitchTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.WhileLoopTree;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTaskImpl;
+
+import jdk.jshell.SourceCodeAnalysis;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.lang.Integer.max;
+import static java.lang.Integer.min;
+import static jdk.jshell.SourceCodeAnalysis.Completeness.*;
+
+public class CompletenessStressTest extends KullaTesting {
+    public final static String JDK_ROOT_SRC_PROP = "jdk.root.src";
+    public final static String JDK_ROOT_SRC;
+
+    static {
+        JDK_ROOT_SRC = System.getProperty(JDK_ROOT_SRC_PROP);
+    }
+
+    public File getSourceFile(String fileName) {
+        for (File dir : getDirectoriesToTest()) {
+            File file = new File(dir, fileName);
+            if (file.exists()) {
+                return file;
+            }
+        }
+        throw new AssertionError("File not found: " + fileName);
+    }
+
+    public File[] getDirectoriesToTest() {
+        return new File[]{
+                new File(JDK_ROOT_SRC, "nashorn/src"),
+                new File(JDK_ROOT_SRC, "langtools/src"),
+                new File(JDK_ROOT_SRC, "jaxp/src"),
+                new File(JDK_ROOT_SRC, "jaxws/src"),
+                new File(JDK_ROOT_SRC, "jdk/src"),
+                new File(JDK_ROOT_SRC, "corba/src")
+        };
+    }
+
+    @DataProvider(name = "crawler")
+    public Object[][] dataProvider() throws IOException {
+        File[] srcDirs = getDirectoriesToTest();
+        List<String[]> list = new ArrayList<>();
+        for (File srcDir : srcDirs) {
+            String srcDirName = srcDir.getAbsolutePath();
+            // this is just to obtain pretty test names for testng tests
+            List<String[]> a = Files.walk(Paths.get(srcDirName))
+                    .map(Path::toFile)
+                    .map(File::getAbsolutePath)
+                    .filter(n -> n.endsWith(".java"))
+                    .map(n -> n.replace(srcDirName, ""))
+                    .map(n -> new String[]{n})
+                    .collect(Collectors.toList());
+            if (a.isEmpty()) {
+                throw new AssertionError("Java sources have not been found in directory: " + srcDirName);
+            }
+            list.addAll(a);
+        }
+        return list.toArray(new String[list.size()][]);
+    }
+
+    @Test(dataProvider = "crawler")
+    public void testFile(String fileName) throws IOException {
+        File file = getSourceFile(fileName);
+        final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        final StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+        boolean success = true;
+        StringWriter writer = new StringWriter();
+        writer.write("Testing : " + file.toString() + "\n");
+        String text = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
+        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(file);
+        JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fileManager, null, null, null, compilationUnits);
+        Iterable<? extends CompilationUnitTree> asts = task.parse();
+        Trees trees = Trees.instance(task);
+        SourcePositions sp = trees.getSourcePositions();
+
+        for (CompilationUnitTree cut : asts) {
+            for (ImportTree imp : cut.getImports()) {
+                success &= testStatement(writer, sp, text, cut, imp);
+            }
+            for (Tree decl : cut.getTypeDecls()) {
+                success &= testStatement(writer, sp, text, cut, decl);
+                if (decl instanceof ClassTree) {
+                    ClassTree ct = (ClassTree) decl;
+                    for (Tree mem : ct.getMembers()) {
+                        if (mem instanceof MethodTree) {
+                            MethodTree mt = (MethodTree) mem;
+                            BlockTree bt = mt.getBody();
+                            // No abstract methods or constructors
+                            if (bt != null && mt.getReturnType() != null) {
+                                // The modifiers synchronized, abstract, and default are not allowed on
+                                // top-level declarations and are errors.
+                                Set<Modifier> modifier = mt.getModifiers().getFlags();
+                                if (!modifier.contains(Modifier.ABSTRACT)
+                                        && !modifier.contains(Modifier.SYNCHRONIZED)
+                                        && !modifier.contains(Modifier.DEFAULT)) {
+                                    success &= testStatement(writer, sp, text, cut, mt);
+                                }
+                                testBlock(writer, sp, text, cut, bt);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        fileManager.close();
+        if (!success) {
+            throw new AssertionError(writer.toString());
+        }
+    }
+
+    private boolean isLegal(StatementTree st) {
+        return !(st instanceof ReturnTree) &&
+                !(st instanceof ContinueTree) && !(st instanceof BreakTree);
+    }
+
+    private boolean testBranch(StringWriter writer, SourcePositions sp, String text, CompilationUnitTree cut, StatementTree statementTree) {
+        if (statementTree instanceof BlockTree) {
+            return testBlock(writer, sp, text, cut, (BlockTree) statementTree);
+        } else if (isLegal(statementTree)) {
+            return testStatement(writer, sp, text, cut, statementTree);
+        }
+        return true;
+    }
+
+    private boolean testBlock(StringWriter writer, SourcePositions sp, String text, CompilationUnitTree cut, BlockTree blockTree) {
+        boolean success = true;
+        for (StatementTree st : blockTree.getStatements()) {
+            if (isLegal(st)) {
+                success &= testStatement(writer, sp, text, cut, st);
+            }
+            if (st instanceof IfTree) {
+                IfTree ifTree = (IfTree) st;
+                success &= testBranch(writer, sp, text, cut, ifTree.getThenStatement());
+                success &= testBranch(writer, sp, text, cut, ifTree.getElseStatement());
+            } else if (st instanceof WhileLoopTree) {
+                WhileLoopTree whileLoopTree = (WhileLoopTree) st;
+                success &= testBranch(writer, sp, text, cut, whileLoopTree.getStatement());
+            } else if (st instanceof DoWhileLoopTree) {
+                DoWhileLoopTree doWhileLoopTree = (DoWhileLoopTree) st;
+                success &= testBranch(writer, sp, text, cut, doWhileLoopTree.getStatement());
+            } else if (st instanceof ForLoopTree) {
+                ForLoopTree forLoopTree = (ForLoopTree) st;
+                success &= testBranch(writer, sp, text, cut, forLoopTree.getStatement());
+            } else if (st instanceof LabeledStatementTree) {
+                LabeledStatementTree labelTree = (LabeledStatementTree) st;
+                success &= testBranch(writer, sp, text, cut, labelTree.getStatement());
+            } else if (st instanceof SwitchTree) {
+                SwitchTree switchTree = (SwitchTree) st;
+                for (CaseTree caseTree : switchTree.getCases()) {
+                    for (StatementTree statementTree : caseTree.getStatements()) {
+                        success &= testBranch(writer, sp, text, cut, statementTree);
+                    }
+                }
+            }
+        }
+        return success;
+    }
+
+    private boolean testStatement(StringWriter writer, SourcePositions sp, String text, CompilationUnitTree cut, Tree statement) {
+        if (statement == null) {
+            return true;
+        }
+        int start = (int) sp.getStartPosition(cut, statement);
+        int end = (int) sp.getEndPosition(cut, statement);
+        char ch = text.charAt(end - 1);
+        SourceCodeAnalysis.Completeness expected = COMPLETE;
+        LineMap lineMap = cut.getLineMap();
+        int row = (int) lineMap.getLineNumber(start);
+        int column = (int) lineMap.getColumnNumber(start);
+        switch (ch) {
+            case ',':
+            case ';':
+                expected = (statement instanceof ExpressionStatementTree)
+                        ? COMPLETE
+                        : COMPLETE_WITH_SEMI;
+                --end;
+                break;
+            case '}':
+                break;
+            default:
+                writer.write(String.format("Unexpected end: row %d, column %d: '%c' -- %s\n",
+                        row, column, ch, text.substring(start, end)));
+                return true;
+        }
+        String unit = text.substring(start, end);
+        SourceCodeAnalysis.CompletionInfo ci = getAnalysis().analyzeCompletion(unit);
+        if (ci.completeness != expected) {
+            if (expected == COMPLETE_WITH_SEMI && (ci.completeness == CONSIDERED_INCOMPLETE || ci.completeness == EMPTY)) {
+                writer.write(String.format("Empty statement: row %d, column %d: -- %s\n",
+                        start, end, unit));
+            } else {
+                String oops = unit.substring(max(0, ci.unitEndPos - 10), ci.unitEndPos) + "|||" +
+                        unit.substring(ci.unitEndPos, min(unit.length(), ci.unitEndPos + 10));
+                writer.write(String.format("Expected %s got %s: '%s'  row %d, column %d: -- %s\n",
+                        expected, ci.completeness, oops, row, column, unit));
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/langtools/test/jdk/jshell/CompletenessTest.java b/langtools/test/jdk/jshell/CompletenessTest.java
new file mode 100644
index 0000000..893baee
--- /dev/null
+++ b/langtools/test/jdk/jshell/CompletenessTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 SourceCodeAnalysis
+ * @build KullaTesting TestingInputStream
+ * @run testng CompletenessTest
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.testng.annotations.Test;
+import jdk.jshell.SourceCodeAnalysis.Completeness;
+
+import static jdk.jshell.SourceCodeAnalysis.Completeness.*;
+
+@Test
+public class CompletenessTest extends KullaTesting {
+
+    // Add complete units that end with semicolon to complete_with_semi (without
+    // the semicolon).  Both cases will be tested.
+    static final String[] complete = new String[] {
+        "{ x= 4; }",
+        "int mm(int x) {kll}",
+        "if (t) { ddd; }",
+        "for (int i = 0; i < lines.length(); ++i) { foo }",
+        "while (ct == null) { switch (current.kind) { case EOF: { } } }",
+        "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) { new CT(UNMATCHED, current, \"Unmatched \" + unmatched); }",
+        "enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); }",
+        "List<T> f() { return null; }",
+        "List<?> f() { return null; }",
+        "List<? extends Object> f() { return null; }",
+        "Map<? extends Object, ? super Object> f() { return null; }",
+        "class C { int z; }",
+        "synchronized (r) { f(); }",
+        "try { } catch (Exception ex) { }",
+        "try { } catch (Exception ex) { } finally { }",
+        "try { } finally { }",
+        "try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)) { }",
+        "foo: while (true) { printf(\"Innn\"); break foo; }",
+        ";",
+    };
+
+    static final String[] expression = new String[] {
+        "test",
+        "x + y",
+        "x + y ++",
+        "p = 9",
+        "match(BRACKETS, TokenKind.LBRACKET)",
+        "new C()",
+        "new C() { public String toString() { return \"Hi\"; } }",
+        "new int[]",
+        "new int[] {1, 2,3}",
+        "new Foo() {}",
+        "i >= 0 && Character.isWhitespace(s.charAt(i))",
+    };
+
+    static final String[] complete_with_semi = new String[] {
+        "int mm",
+        "if (t) ddd",
+        "int p = 9",
+        "int p",
+        "Deque<Token> stack = new ArrayDeque<>()",
+        "final Deque<Token> stack = new ArrayDeque<>()",
+        "java.util.Scanner input = new java.util.Scanner(System.in)",
+        "java.util.Scanner input = new java.util.Scanner(System.in) { }",
+        "int j = -i",
+        "String[] a = { \"AAA\" }",
+        "assert true",
+        "int path[]",
+        "int path[][]",
+        "int path[][] = new int[22][]",
+        "int path[] = new int[22]",
+        "int path[] = new int[] {1, 2, 3}",
+        "int[] path",
+        "int path[] = new int[22]",
+        "int path[][] = new int[22][]",
+        "for (Object o : a) System.out.println(\"Yep\")",
+        "while (os == null) System.out.println(\"Yep\")",
+        "do f(); while (t)",
+        "if (os == null) System.out.println(\"Yep\")",
+        "if (t) if (!t) System.out.println(123)",
+        "for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else break",
+        "for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else continue",
+        "for (int i = 0; i < 10; ++i) if (i < 5) System.out.println(i); else return",
+        "throw ex",
+        "C c = new C()",
+        "java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName)",
+        "BufferedReader br = new BufferedReader(new FileReader(path))",
+        "bar: g()",
+        "baz: while (true) if (t()) printf('-'); else break baz",
+    };
+
+    static final String[] considered_incomplete = new String[] {
+        "if (t)",
+        "if (t) { } else",
+        "if (t) if (!t)",
+        "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE))",
+        "for (int i = 0; i < 10; ++i)",
+        "while (os == null)",
+    };
+
+    static final String[] definitely_incomplete = new String[] {
+        "int mm(",
+        "int mm(int x",
+        "int mm(int x)",
+        "int mm(int x) {",
+        "int mm(int x) {kll",
+        "if",
+        "if (",
+        "if (t",
+        "if (t) {",
+        "if (t) { ddd",
+        "if (t) { ddd;",
+        "if (t) if (",
+        "if (stack.isEmpty()) {",
+        "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) {",
+        "if (match.kind == BRACES && (prevCT.kind == ARROW || prevCT.kind == NEW_MIDDLE)) { new CT(UNMATCHED, current, \"Unmatched \" + unmatched);",
+        "x +",
+        "int",
+        "for (int i = 0; i < lines.length(); ++i) {",
+        "new",
+        "new C(",
+        "new int[",
+        "new int[] {1, 2,3",
+        "new int[] {",
+        "while (ct == null) {",
+        "while (ct == null) { switch (current.kind) {",
+        "while (ct == null) { switch (current.kind) { case EOF: {",
+        "while (ct == null) { switch (current.kind) { case EOF: { } }",
+        "enum TK {",
+        "enum TK { EOF(TokenKind.EOF, 0),",
+        "enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM)",
+        "enum TK { EOF(TokenKind.EOF, 0), NEW_MIDDLE(XEXPR1|XTERM); ",
+    };
+
+    static final String[] unknown = new String[] {
+        "new ;"
+    };
+
+    static final Map<Completeness, String[]> statusToCases = new HashMap<>();
+    static {
+        statusToCases.put(COMPLETE, complete);
+        statusToCases.put(COMPLETE_WITH_SEMI, complete_with_semi);
+        statusToCases.put(CONSIDERED_INCOMPLETE, considered_incomplete);
+        statusToCases.put(DEFINITELY_INCOMPLETE, definitely_incomplete);
+    }
+
+    private void assertStatus(String input, Completeness status, String source) {
+        String augSrc;
+        switch (status) {
+            case COMPLETE_WITH_SEMI:
+                augSrc = source + ";";
+                break;
+
+            case DEFINITELY_INCOMPLETE:
+            case CONSIDERED_INCOMPLETE:
+                augSrc = null;
+                break;
+
+            case EMPTY:
+            case COMPLETE:
+            case UNKNOWN:
+                augSrc = source;
+                break;
+
+            default:
+                throw new AssertionError();
+        }
+        assertAnalyze(input, status, augSrc);
+    }
+
+    private void assertStatus(String[] ins, Completeness status) {
+        for (String input : ins) {
+            assertStatus(input, status, input);
+        }
+    }
+
+    public void test_complete() {
+        assertStatus(complete, COMPLETE);
+    }
+
+    public void test_expression() {
+        assertStatus(expression, COMPLETE);
+    }
+
+    public void test_complete_with_semi() {
+        assertStatus(complete_with_semi, COMPLETE_WITH_SEMI);
+    }
+
+    public void test_considered_incomplete() {
+        assertStatus(considered_incomplete, CONSIDERED_INCOMPLETE);
+    }
+
+    public void test_definitely_incomplete() {
+        assertStatus(definitely_incomplete, DEFINITELY_INCOMPLETE);
+    }
+
+    public void test_unknown() {
+        assertStatus(definitely_incomplete, DEFINITELY_INCOMPLETE);
+    }
+
+    public void testCompleted_complete_with_semi() {
+        for (String in : complete_with_semi) {
+            String input = in + ";";
+            assertStatus(input, COMPLETE, input);
+        }
+    }
+
+    public void testCompleted_expression_with_semi() {
+        for (String in : expression) {
+            String input = in + ";";
+            assertStatus(input, COMPLETE, input);
+        }
+    }
+
+    public void testCompleted_considered_incomplete() {
+        for (String in : considered_incomplete) {
+            String input = in + ";";
+            assertStatus(input, COMPLETE, input);
+        }
+    }
+
+    private void assertSourceByStatus(String first) {
+        for (Map.Entry<Completeness, String[]> e : statusToCases.entrySet()) {
+            for (String in : e.getValue()) {
+                String input = first + in;
+                assertAnalyze(input, COMPLETE, first, in, true);
+            }
+        }
+    }
+
+    public void testCompleteSource_complete() {
+        for (String input : complete) {
+            assertSourceByStatus(input);
+        }
+    }
+
+    public void testCompleteSource_complete_with_semi() {
+        for (String in : complete_with_semi) {
+            String input = in + ";";
+            assertSourceByStatus(input);
+        }
+    }
+
+    public void testCompleteSource_expression() {
+        for (String in : expression) {
+            String input = in + ";";
+            assertSourceByStatus(input);
+        }
+    }
+
+    public void testCompleteSource_considered_incomplete() {
+        for (String in : considered_incomplete) {
+            String input = in + ";";
+            assertSourceByStatus(input);
+        }
+    }
+
+    public void testTrailingSlash() {
+        assertStatus("\"abc\\", UNKNOWN, "\"abc\\");
+    }
+
+    public void testMiscSource() {
+        assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
+        assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
+        assertStatus("int p = ", DEFINITELY_INCOMPLETE, "int p ="); //Bug
+    }
+}
diff --git a/langtools/test/jdk/jshell/CompletionSuggestionTest.java b/langtools/test/jdk/jshell/CompletionSuggestionTest.java
new file mode 100644
index 0000000..1f27d0c
--- /dev/null
+++ b/langtools/test/jdk/jshell/CompletionSuggestionTest.java
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Completion
+ * @library /tools/lib
+ * @build KullaTesting TestingInputStream ToolBox Compiler
+ * @run testng CompletionSuggestionTest
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import java.util.HashSet;
+
+import jdk.jshell.Snippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+
+@Test
+public class CompletionSuggestionTest extends KullaTesting {
+
+    public void testMemberExpr() {
+        assertEval("class Test { static void test() { } }");
+        assertCompletion("Test.t|", "test()");
+        assertEval("Test ccTestInstance = new Test();");
+        assertCompletion("ccTestInstance.t|", "toString()");
+        assertCompletion(" ccTe|", "ccTestInstance");
+        assertCompletion("String value = ccTestInstance.to|", "toString()");
+        assertCompletion("java.util.Coll|", "Collection", "Collections");
+        assertCompletion("String.cla|", "class");
+        assertCompletion("boolean.cla|", "class");
+        assertCompletion("byte.cla|", "class");
+        assertCompletion("short.cla|", "class");
+        assertCompletion("char.cla|", "class");
+        assertCompletion("int.cla|", "class");
+        assertCompletion("float.cla|", "class");
+        assertCompletion("long.cla|", "class");
+        assertCompletion("double.cla|", "class");
+        assertCompletion("void.cla|", "class");
+        assertCompletion("Object[].|", "class");
+        assertCompletion("int[].|", "class");
+        assertEval("Object[] ao = null;");
+        assertCompletion("int i = ao.|", "length");
+        assertEval("int[] ai = null;");
+        assertCompletion("int i = ai.|", "length");
+        assertCompletionIncludesExcludes("\"\".|",
+                new HashSet<>(Collections.emptyList()),
+                new HashSet<>(Arrays.asList("String(")));
+        assertEval("double d = 0;");
+        assertEval("void m() {}");
+        assertCompletionIncludesExcludes("d.|",
+                new HashSet<>(Collections.emptyList()),
+                new HashSet<>(Arrays.asList("class")));
+        assertCompletionIncludesExcludes("m().|",
+                new HashSet<>(Collections.emptyList()),
+                new HashSet<>(Arrays.asList("class")));
+        assertEval("class C {class D {} static class E {} enum F {} interface H {} void method() {} int number;}");
+        assertCompletionIncludesExcludes("C.|",
+                new HashSet<>(Arrays.asList("D", "E", "F", "H", "class")),
+                new HashSet<>(Arrays.asList("method()", "number")));
+        assertCompletionIncludesExcludes("new C().|",
+                new HashSet<>(Arrays.asList("method()", "number")),
+                new HashSet<>(Arrays.asList("D", "E", "F", "H", "class")));
+        assertCompletionIncludesExcludes("new C() {}.|",
+                new HashSet<>(Arrays.asList("method()", "number")),
+                new HashSet<>(Arrays.asList("D", "E", "F", "H", "class")));
+    }
+
+    public void testStartOfExpression() {
+        assertEval("int ccTest = 0;");
+        assertCompletion("System.err.println(cc|", "ccTest");
+        assertCompletion("for (int i = cc|", "ccTest");
+    }
+
+    public void testParameter() {
+        assertCompletion("class C{void method(int num){num|", "num");
+    }
+
+    public void testPrimitive() {
+        Set<String> primitives = new HashSet<>(Arrays.asList("boolean", "char", "byte", "short", "int", "long", "float", "double"));
+        Set<String> onlyVoid = new HashSet<>(Collections.singletonList("void"));
+        Set<String> primitivesOrVoid = new HashSet<>(primitives);
+        primitivesOrVoid.addAll(onlyVoid);
+
+        assertCompletionIncludesExcludes("|",
+                primitivesOrVoid,
+                new HashSet<>(Collections.emptyList()));
+        assertCompletionIncludesExcludes("int num = |",
+                primitivesOrVoid,
+                new HashSet<>(Collections.emptyList()));
+        assertCompletionIncludesExcludes("num = |",
+                primitivesOrVoid,
+                new HashSet<>(Collections.emptyList()));
+        assertCompletionIncludesExcludes("class C{void m() {|",
+                primitivesOrVoid,
+                new HashSet<>(Collections.emptyList()));
+        assertCompletionIncludesExcludes("void method(|",
+                primitives,
+                onlyVoid);
+        assertCompletionIncludesExcludes("void method(int num, |",
+                primitives,
+                onlyVoid);
+        assertCompletion("new java.util.ArrayList<doub|");
+        assertCompletion("class A extends doubl|");
+        assertCompletion("class A implements doubl|");
+        assertCompletion("interface A extends doubl|");
+        assertCompletion("enum A implements doubl|");
+        assertCompletion("class A<T extends doubl|");
+    }
+
+    public void testEmpty() {
+        assertCompletionIncludesExcludes("|",
+                new HashSet<>(Arrays.asList("Object", "Void")),
+                new HashSet<>(Arrays.asList("$REPL00DOESNOTMATTER")));
+        assertCompletionIncludesExcludes("V|",
+                new HashSet<>(Collections.singletonList("Void")),
+                new HashSet<>(Collections.singletonList("Object")));
+        assertCompletionIncludesExcludes("{ |",
+                new HashSet<>(Arrays.asList("Object", "Void")),
+                new HashSet<>(Arrays.asList("$REPL00DOESNOTMATTER")));
+    }
+
+    public void testSmartCompletion() {
+        assertEval("int ccTest1 = 0;");
+        assertEval("int ccTest2 = 0;");
+        assertEval("String ccTest3 = null;");
+        assertEval("void method(int i, String str) { }");
+        assertEval("void method(String str, int i) { }");
+        assertEval("java.util.List<String> list = null;");
+        assertCompletion("int ccTest4 = |", true, "ccTest1", "ccTest2");
+        assertCompletion("ccTest2 = |", true, "ccTest1", "ccTest2");
+        assertCompletion("int ccTest4 = ccTe|", "ccTest1", "ccTest2", "ccTest3");
+        assertCompletion("int ccTest4 = ccTest3.len|", true, "length()");
+        assertCompletion("method(|", true, "ccTest1", "ccTest2", "ccTest3");
+        assertCompletion("method(0, |", true, "ccTest3");
+        assertCompletion("list.add(|", true, "ccTest1", "ccTest2", "ccTest3");
+        assertCompletion("list.add(0, |", true, "ccTest3");
+        assertCompletion("new String(|", true, "ccTest3");
+        assertCompletion("new String(new char[0], |", true, "ccTest1", "ccTest2");
+        assertCompletionIncludesExcludes("new jav|", new HashSet<>(Arrays.asList("java", "javax")), Collections.emptySet());
+        assertCompletion("Class<String> clazz = String.c|", true, "class");
+
+        Snippet klass = classKey(assertEval("class Klass {void method(int n) {} private void method(String str) {}}"));
+        assertCompletion("new Klass().method(|", true, "ccTest1", "ccTest2");
+        Snippet klass2 = classKey(assertEval("class Klass {static void method(int n) {} void method(String str) {}}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(klass, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertCompletion("Klass.method(|", true, "ccTest1", "ccTest2");
+        assertEval("class Klass {Klass(int n) {} private Klass(String str) {}}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(klass2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertCompletion("new Klass(|", true, "ccTest1", "ccTest2");
+    }
+
+    public void testSmartCompletionInOverriddenMethodInvocation() {
+        assertEval("int ccTest1 = 0;");
+        assertEval("int ccTest2 = 0;");
+        assertEval("String ccTest3 = null;");
+        assertCompletion("\"\".wait(|", true, "ccTest1", "ccTest2");
+        assertEval("class Base {void method(int n) {}}");
+        assertEval("class Extend extends Base {}");
+        assertCompletion("new Extend().method(|", true, "ccTest1", "ccTest2");
+    }
+
+    public void testSmartCompletionForBoxedType() {
+        assertEval("int ccTest1 = 0;");
+        assertEval("Integer ccTest2 = 0;");
+        assertEval("Object ccTest3 = null;");
+        assertEval("int method1(int n) {return n;}");
+        assertEval("Integer method2(Integer n) {return n;}");
+        assertEval("Object method3(Object o) {return o;}");
+        assertCompletion("int ccTest4 = |", true, "ccTest1", "ccTest2", "method1(", "method2(");
+        assertCompletion("Integer ccTest4 = |", true, "ccTest1", "ccTest2", "method1(", "method2(");
+        assertCompletion("Object ccTest4 = |", true, "ccTest1", "ccTest2", "ccTest3", "method1(", "method2(", "method3(");
+        assertCompletion("method1(|", true, "ccTest1", "ccTest2", "method1(", "method2(");
+        assertCompletion("method2(|", true, "ccTest1", "ccTest2", "method1(", "method2(");
+        assertCompletion("method3(|", true, "ccTest1", "ccTest2", "ccTest3", "method1(", "method2(", "method3(");
+    }
+
+    public void testNewClass() {
+        assertCompletion("String str = new Strin|", "String(", "StringBuffer(", "StringBuilder(", "StringIndexOutOfBoundsException(");
+        assertCompletion("String str = new java.lang.Strin|", "String(", "StringBuffer(", "StringBuilder(", "StringIndexOutOfBoundsException(");
+        assertCompletion("String str = new |", true, "String(");
+        assertCompletion("String str = new java.lang.|", true, "String(");
+        assertCompletion("throw new Strin|", true, "StringIndexOutOfBoundsException(");
+
+        assertEval("class A{class B{} class C {C(int n) {}} static class D {} interface I {}}");
+        assertEval("A a;");
+        assertCompletion("new A().new |", "B()", "C(");
+        assertCompletion("a.new |", "B()", "C(");
+        assertCompletion("new A.|", "D()");
+
+        assertEval("enum E{; class A {}}");
+        assertEval("interface I{; class A {}}");
+        assertCompletion("new E.|", "A()");
+        assertCompletion("new I.|", "A()");
+        assertCompletion("new String(I.A|", "A");
+    }
+
+    public void testFullyQualified() {
+        assertCompletion("Optional<String> opt = java.u|", "util");
+        assertCompletionIncludesExcludes("Optional<Strings> opt = java.util.O|", new HashSet<>(Collections.singletonList("Optional")), Collections.emptySet());
+
+        assertEval("void method(java.util.Optional<String> opt) {}");
+        assertCompletion("method(java.u|", "util");
+
+        assertCompletion("Object.notElement.|");
+        assertCompletion("Object o = com.su|", "sun");
+    }
+
+    public void testCheckAccessibility() {
+        assertCompletion("java.util.regex.Pattern.co|", "compile(");
+    }
+
+    public void testCompletePackages() {
+        assertCompletion("java.u|", "util");
+        assertCompletionIncludesExcludes("jav|", new HashSet<>(Arrays.asList("java", "javax")), Collections.emptySet());
+    }
+
+    public void testImports() {
+        assertCompletion("import java.u|", "util");
+        assertCompletionIncludesExcludes("import jav|", new HashSet<>(Arrays.asList("java", "javax")), Collections.emptySet());
+        assertCompletion("import static java.u|", "util");
+        assertCompletionIncludesExcludes("import static jav|", new HashSet<>(Arrays.asList("java", "javax")), Collections.emptySet());
+        assertCompletion("import static java.lang.Boolean.g|", "getBoolean");
+        assertCompletion("import java.util.*|");
+        assertCompletionIncludesExcludes("import java.lang.String.|",
+                Collections.emptySet(),
+                new HashSet<>(Arrays.asList("CASE_INSENSITIVE_ORDER", "copyValueOf", "format", "join", "valueOf", "class", "length")));
+        assertCompletionIncludesExcludes("import static java.lang.String.|",
+                new HashSet<>(Arrays.asList("CASE_INSENSITIVE_ORDER", "copyValueOf", "format", "join", "valueOf")),
+                new HashSet<>(Arrays.asList("class", "length")));
+        assertCompletionIncludesExcludes("import java.util.Map.|",
+                new HashSet<>(Arrays.asList("Entry")),
+                new HashSet<>(Arrays.asList("class")));
+    }
+
+    public void testBrokenClassFile() throws Exception {
+        Compiler compiler = new Compiler();
+        Path testOutDir = Paths.get("CompletionTestBrokenClassFile");
+        String input = "package test.inner; public class Test {}";
+        compiler.compile(testOutDir, input);
+        addToClasspath(compiler.getPath(testOutDir).resolve("test"));
+        assertCompletion("import inner.|");
+    }
+
+    public void testDocumentation() {
+        assertDocumentation("System.getProperty(|",
+                "java.lang.System.getProperty(java.lang.String arg0)",
+                "java.lang.System.getProperty(java.lang.String arg0, java.lang.String arg1)");
+        assertEval("char[] chars = null;");
+        assertDocumentation("new String(chars, |",
+                "java.lang.String(char[] arg0, int arg1, int arg2)");
+        assertDocumentation("String.format(|",
+                "java.lang.String.format(java.lang.String arg0, java.lang.Object... arg1)",
+                "java.lang.String.format(java.util.Locale arg0, java.lang.String arg1, java.lang.Object... arg2)");
+        assertDocumentation("\"\".getBytes(\"\"|", "java.lang.String.getBytes(int arg0, int arg1, byte[] arg2, int arg3)",
+                                                    "java.lang.String.getBytes(java.lang.String arg0)",
+                                                    "java.lang.String.getBytes(java.nio.charset.Charset arg0)");
+        assertDocumentation("\"\".getBytes(\"\" |", "java.lang.String.getBytes(int arg0, int arg1, byte[] arg2, int arg3)",
+                                                     "java.lang.String.getBytes(java.lang.String arg0)",
+                                                     "java.lang.String.getBytes(java.nio.charset.Charset arg0)");
+    }
+
+    public void testMethodsWithNoArguments() {
+        assertDocumentation("System.out.println(|",
+                "java.io.PrintStream.println()",
+                "java.io.PrintStream.println(boolean arg0)",
+                "java.io.PrintStream.println(char arg0)",
+                "java.io.PrintStream.println(int arg0)",
+                "java.io.PrintStream.println(long arg0)",
+                "java.io.PrintStream.println(float arg0)",
+                "java.io.PrintStream.println(double arg0)",
+                "java.io.PrintStream.println(char[] arg0)",
+                "java.io.PrintStream.println(java.lang.String arg0)",
+                "java.io.PrintStream.println(java.lang.Object arg0)");
+    }
+
+    public void testErroneous() {
+        assertCompletion("Undefined.|");
+    }
+
+    public void testClinit() {
+        assertEval("enum E{;}");
+        assertEval("class C{static{}}");
+        assertCompletionIncludesExcludes("E.|", Collections.emptySet(), new HashSet<>(Collections.singletonList("<clinit>")));
+        assertCompletionIncludesExcludes("C.|", Collections.emptySet(), new HashSet<>(Collections.singletonList("<clinit>")));
+    }
+
+    public void testMethodHeaderContext() {
+        assertCompletion("private void f(Runn|", "Runnable");
+        assertCompletion("void f(Runn|", "Runnable");
+        assertCompletion("void f(Object o1, Runn|", "Runnable");
+        assertCompletion("void f(Object o1) throws Num|", true, "NumberFormatException");
+        assertCompletion("void f(Object o1) throws java.lang.Num|", true, "NumberFormatException");
+        assertEval("class HogeHoge {static class HogeHogeException extends Exception {}}");
+        assertCompletion("void f(Object o1) throws Hoge|", "HogeHoge");
+        assertCompletion("void f(Object o1) throws HogeHoge.|", true, "HogeHogeException");
+    }
+
+    public void testTypeVariables() {
+        assertCompletion("class A<TYPE> { public void test() { TY|", "TYPE");
+        assertCompletion("class A<TYPE> { public static void test() { TY|");
+        assertCompletion("class A<TYPE> { public <TYPE> void test() { TY|", "TYPE");
+        assertCompletion("class A<TYPE> { public static <TYPE> void test() { TY|", "TYPE");
+    }
+
+    public void testGeneric() {
+        assertEval("import java.util.concurrent.*;");
+        assertCompletion("java.util.List<Integ|", "Integer");
+        assertCompletion("class A<TYPE extends Call|", "Callable");
+        assertCompletion("class A<TYPE extends Callable<TY|", "TYPE");
+        assertCompletion("<TYPE> void f(TY|", "TYPE");
+        assertCompletion("class A<TYPE extends Callable<? sup|", "super");
+        assertCompletion("class A<TYPE extends Callable<? super TY|", "TYPE");
+    }
+
+    public void testFields() {
+        assertEval("interface Interface { int field = 0; }");
+        Snippet clazz = classKey(assertEval("class Clazz {" +
+                "static int staticField = 0;" +
+                "int field = 0;" +
+                " }"));
+        assertCompletion("Interface.fiel|", "field");
+        assertCompletion("Clazz.staticFiel|", "staticField");
+        assertCompletion("new Interface() {}.fiel|");
+        assertCompletion("new Clazz().staticFiel|");
+        assertCompletion("new Clazz().fiel|", "field");
+        assertCompletion("new Clazz() {}.fiel|", "field");
+        assertEval("class Clazz implements Interface {}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(clazz, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertCompletion("Clazz.fiel|", "field");
+        assertCompletion("new Clazz().fiel|");
+        assertCompletion("new Clazz() {}.fiel|");
+    }
+
+    public void testMethods() {
+        assertEval("interface Interface {" +
+                "default int defaultMethod() { return 0; }" +
+                "static int staticMethod() { return 0; }" +
+                "}");
+        Snippet clazz = classKey(assertEval("class Clazz {" +
+                "static int staticMethod() { return 0; }" +
+                "int method() { return 0; }" +
+                "}"));
+        assertCompletion("Interface.staticMeth|", "staticMethod()");
+        assertCompletion("Clazz.staticMeth|", "staticMethod()");
+        assertCompletion("new Interface() {}.defaultMe||", "defaultMethod()");
+        assertCompletion("new Clazz().staticMeth|");
+        assertCompletion("new Clazz().meth|", "method()");
+        assertEval("class Clazz implements Interface {}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(clazz, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertCompletion("Clazz.staticMeth|");
+        assertCompletion("new Clazz() {}.defaultM|", "defaultMethod()");
+    }
+
+    @Test(enabled = false) // TODO 8129422
+    public void testUncompletedDeclaration() {
+        assertCompletion("class Clazz { Claz|", "Clazz");
+        assertCompletion("class Clazz { class A extends Claz|", "Clazz");
+        assertCompletion("class Clazz { Clazz clazz; Object o = cla|", "clazz");
+        assertCompletion("class Clazz { static Clazz clazz; Object o = cla|", "clazz");
+        assertCompletion("class Clazz { Clazz clazz; static Object o = cla|", true);
+        assertCompletion("class Clazz { void method(Claz|", "Clazz");
+        assertCompletion("class A { int method() { return 0; } int a = meth|", "method");
+        assertCompletion("class A { int field = 0; int method() { return fiel|", "field");
+        assertCompletion("class A { static int method() { return 0; } int a = meth|", "method");
+        assertCompletion("class A { static int field = 0; int method() { return fiel|", "field");
+        assertCompletion("class A { int method() { return 0; } static int a = meth|", true);
+        assertCompletion("class A { int field = 0; static int method() { return fiel|", true);
+    }
+
+    @Test(enabled = false) // TODO 8129421
+    public void testClassDeclaration() {
+        assertEval("interface Interface {}");
+        assertCompletion("interface A extends Interf|", "Interface");
+        assertCompletion("class A implements Interf|", "Interface");
+        assertEval("class Clazz {}");
+        assertCompletion("class A extends Claz|", "Clazz");
+        assertCompletion("class A extends Clazz implements Interf|", "Interface");
+        assertEval("interface Interface1 {}");
+        assertCompletion("class A extends Clazz implements Interface, Interf|", "Interface", "Interface1");
+        assertCompletion("interface A implements Claz|");
+        assertCompletion("interface A implements Inter|");
+        assertCompletion("class A implements Claz|", true);
+        assertCompletion("class A extends Clazz implements Interface, Interf|", true, "Interface1");
+    }
+
+    public void testDocumentationOfUserDefinedMethods() {
+        assertEval("void f() {}");
+        assertDocumentation("f(|", "f()");
+        assertEval("void f(int a) {}");
+        assertDocumentation("f(|", "f()", "f(int arg0)");
+        assertEval("<T> void f(T... a) {}", DiagCheck.DIAG_WARNING, DiagCheck.DIAG_OK);
+        assertDocumentation("f(|", "f()", "f(int arg0)", "f(T... arg0)");
+        assertEval("class A {}");
+        assertEval("void f(A a) {}");
+        assertDocumentation("f(|", "f()", "f(int arg0)", "f(T... arg0)", "f(A arg0)");
+    }
+
+    public void testDocumentationOfUserDefinedConstructors() {
+        Snippet a = classKey(assertEval("class A {}"));
+        assertDocumentation("new A(|", "A()");
+        Snippet a2 = classKey(assertEval("class A { A() {} A(int a) {}}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertDocumentation("new A(|", "A()", "A(int arg0)");
+        assertEval("class A<T> { A(T a) {} A(int a) {}}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertDocumentation("new A(|", "A(T arg0)", "A(int arg0)");
+    }
+
+    public void testDocumentationOfOverriddenMethods() {
+        assertDocumentation("\"\".wait(|",
+            "java.lang.Object.wait(long arg0)",
+            "java.lang.Object.wait(long arg0, int arg1)",
+            "java.lang.Object.wait()");
+        assertEval("class Base {void method() {}}");
+        Snippet e = classKey(assertEval("class Extend extends Base {}"));
+        assertDocumentation("new Extend().method(|", "Base.method()");
+        assertEval("class Extend extends Base {void method() {}}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(e, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertDocumentation("new Extend().method(|", "Extend.method()");
+    }
+
+    public void testDocumentationOfInvisibleMethods() {
+        assertDocumentation("Object.wait(|", "");
+        assertDocumentation("\"\".indexOfSupplementary(|", "");
+        Snippet a = classKey(assertEval("class A {void method() {}}"));
+        assertDocumentation("A.method(|", "");
+        assertEval("class A {private void method() {}}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertDocumentation("new A().method(|", "");
+    }
+
+    public void testDocumentationOfInvisibleConstructors() {
+        assertDocumentation("new Compiler(|", "");
+        assertEval("class A { private A() {} }");
+        assertDocumentation("new A(|", "");
+    }
+
+    public void testDocumentationWithBoxing() {
+        assertEval("int primitive = 0;");
+        assertEval("Integer boxed = 0;");
+        assertEval("Object object = null;");
+        assertEval("void method(int n, Object o) { }");
+        assertEval("void method(Object n, int o) { }");
+        assertDocumentation("method(primitive,|",
+                "method(int arg0, java.lang.Object arg1)",
+                "method(java.lang.Object arg0, int arg1)");
+        assertDocumentation("method(boxed,|",
+                "method(int arg0, java.lang.Object arg1)",
+                "method(java.lang.Object arg0, int arg1)");
+        assertDocumentation("method(object,|",
+                "method(java.lang.Object arg0, int arg1)");
+    }
+
+    public void testVarArgs() {
+        assertEval("int i = 0;");
+        assertEval("class Foo1 { static void m(int... i) { } } ");
+        assertCompletion("Foo1.m(|", true, "i");
+        assertCompletion("Foo1.m(i, |", true, "i");
+        assertCompletion("Foo1.m(i, i, |", true, "i");
+        assertEval("class Foo2 { static void m(String s, int... i) { } } ");
+        assertCompletion("Foo2.m(|", true);
+        assertCompletion("Foo2.m(i, |", true);
+        assertCompletion("Foo2.m(\"\", |", true, "i");
+        assertCompletion("Foo2.m(\"\", i, |", true, "i");
+        assertCompletion("Foo2.m(\"\", i, i, |", true, "i");
+        assertEval("class Foo3 { Foo3(String s, int... i) { } } ");
+        assertCompletion("new Foo3(|", true);
+        assertCompletion("new Foo3(i, |", true);
+        assertCompletion("new Foo3(\"\", |", true, "i");
+        assertCompletion("new Foo3(\"\", i, |", true, "i");
+        assertCompletion("new Foo3(\"\", i, i, |", true, "i");
+        assertEval("int[] ia = null;");
+        assertCompletion("Foo1.m(ia, |", true);
+        assertEval("class Foo4 { static void m(int... i) { } static void m(int[] ia, String str) { } } ");
+        assertEval("String str = null;");
+        assertCompletion("Foo4.m(ia, |", true, "str");
+    }
+
+    public void testConstructorAsMemberOf() {
+        assertEval("class Baz<X> { Baz(X x) { } } ");
+        assertEval("String str = null;");
+        assertEval("Integer i = null;");
+        assertCompletion("new Baz(|", true, "i", "str");
+        assertCompletion("new Baz<String>(|", true, "str");
+        assertCompletion("Baz<String> bz = new Baz<>(|", true, "str");
+        assertEval("class Foo { static void m(String str) {} static void m(Baz<String> baz) {} }");
+        assertCompletion("Foo.m(new Baz<>(|", true, "str");
+    }
+}
diff --git a/langtools/test/jdk/jshell/CustomEditor.java b/langtools/test/jdk/jshell/CustomEditor.java
new file mode 100644
index 0000000..f60d032
--- /dev/null
+++ b/langtools/test/jdk/jshell/CustomEditor.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.Socket;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+
+public class CustomEditor implements AutoCloseable {
+
+    public static final int SOURCE_CODE = 0;
+    public static final int GET_SOURCE_CODE = 1;
+    public static final int REMOVE_CODE = 2;
+
+    public static final int EXIT_CODE = -1;
+    public static final int ACCEPT_CODE = -2;
+    public static final int CANCEL_CODE = -3;
+
+    private final Socket socket;
+    private final Path path;
+    private final StringWriter writer;
+    private final String source;
+
+    public CustomEditor(int port, String fileName) throws IOException {
+        this.socket = new Socket((String) null, port);
+        this.path = Paths.get(fileName);
+        this.writer = new StringWriter();
+        this.source = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
+    }
+
+    public void loop() throws IOException {
+        DataInputStream input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
+        DataOutputStream output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
+
+        while (true) {
+            int cmd = input.readInt();
+            switch (cmd) {
+                case EXIT_CODE: {
+                    Files.write(path, Collections.singletonList(writer.toString()));
+                    return;
+                }
+                case GET_SOURCE_CODE: {
+                    byte[] bytes = source.getBytes(StandardCharsets.UTF_8);
+                    output.writeInt(bytes.length);
+                    output.write(bytes);
+                    output.flush();
+                    break;
+                }
+                case REMOVE_CODE: {
+                    // only for external editor
+                    Files.delete(path);
+                    break;
+                }
+                case CANCEL_CODE: {
+                    return;
+                }
+                case ACCEPT_CODE: {
+                    Files.write(path, Collections.singletonList(writer.toString()));
+                    break;
+                }
+                case SOURCE_CODE: {
+                    int length = input.readInt();
+                    byte[] bytes = new byte[length];
+                    input.readFully(bytes);
+                    writer.write(new String(bytes, StandardCharsets.UTF_8));
+                    break;
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        if (args.length != 2) {
+            System.err.println("Usage: port file");
+            System.exit(1);
+        }
+        try (CustomEditor editor = new CustomEditor(Integer.parseInt(args[0]), args[1])) {
+            editor.loop();
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        socket.close();
+    }
+}
diff --git a/langtools/test/jdk/jshell/DropTest.java b/langtools/test/jdk/jshell/DropTest.java
new file mode 100644
index 0000000..a243041
--- /dev/null
+++ b/langtools/test/jdk/jshell/DropTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 of JShell#drop().
+ * @build KullaTesting TestingInputStream
+ * @run testng DropTest
+ */
+
+import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.PersistentSnippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.*;
+
+@Test
+public class DropTest extends KullaTesting {
+
+    public void testDrop() {
+        PersistentSnippet var = varKey(assertEval("int x;"));
+        PersistentSnippet method = methodKey(assertEval("int mu() { return x * 4; }"));
+        PersistentSnippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
+        assertDrop(var,
+                ste(var, VALID, DROPPED, true, null),
+                ste(method, VALID, RECOVERABLE_DEFINED, false, var));
+        //assertDrop(method,
+        //        ste(method, RECOVERABLE_DEFINED, DROPPED, false, null),
+        //        ste(clazz, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, method));
+        //assertDeclareFail("new C();", "compiler.err.cant.resolve.location");
+        assertVariables();
+        assertMethods();
+        assertClasses();
+        assertActiveKeys();
+
+        assertEval("int x = 10;", "10",
+                ste(var, DROPPED, VALID, true, null),
+                ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
+        PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
+        assertEval("c0.v();", "\"#40\"");
+        assertEval("C c = new C();");
+        assertEval("c.v();", "\"#40\"");
+        assertEval("int mu() { return x * 3; }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(method, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("c.v();", "\"#30\"");
+        assertEval("class C { String v() { return \"@\" + mu(); } }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(clazz, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("c0.v();", "\"@30\"");
+        assertDrop(c0,
+                ste(c0, VALID, DROPPED, true, null));
+        assertEval("c = new C();");
+        assertEval("c.v();", "\"@30\"");
+
+        assertVariables();
+        assertMethods();
+        assertClasses();
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081431
+    public void testDropImport() {
+        PersistentSnippet imp = importKey(assertEval("import java.util.*;"));
+        PersistentSnippet decl = varKey(
+                assertEval("List<Integer> list = Arrays.asList(1, 2, 3);", "[1, 2, 3]"));
+        assertEval("list;", "[1, 2, 3]");
+        assertDrop(imp,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(imp, VALID, DROPPED, true, null),
+                ste(decl, VALID, RECOVERABLE_NOT_DEFINED, true, imp));
+        assertDeclareFail("list;", "compiler.err.cant.resolve.location");
+    }
+
+    public void testDropVarToMethod() {
+        PersistentSnippet x = varKey(assertEval("int x;"));
+        DeclarationSnippet method = methodKey(assertEval("double mu() { return x * 4; }"));
+        assertEval("x == 0;", "true");
+        assertEval("mu() == 0.0;", "true");
+
+        assertDrop(x,
+                ste(x, VALID, DROPPED, true, null),
+                ste(method, VALID, RECOVERABLE_DEFINED, false, x));
+        assertUnresolvedDependencies1(method, RECOVERABLE_DEFINED, "variable x");
+        assertEvalUnresolvedException("mu();", "mu", 1, 0);
+
+        assertVariables();
+        assertMethods();
+        assertActiveKeys();
+    }
+
+    public void testDropMethodToMethod() {
+        PersistentSnippet a = methodKey(assertEval("double a() { return 2; }"));
+        DeclarationSnippet b = methodKey(assertEval("double b() { return a() * 10; }"));
+        assertEval("double c() { return b() * 3; }");
+        DeclarationSnippet d = methodKey(assertEval("double d() { return c() + 1000; }"));
+        assertEval("d();", "1060.0");
+        assertDrop(a,
+                ste(a, VALID, DROPPED, true, null),
+                ste(b, VALID, RECOVERABLE_DEFINED, false, a));
+        assertUnresolvedDependencies1(b, RECOVERABLE_DEFINED, "method a()");
+        assertUnresolvedDependencies(d, 0);
+        assertEvalUnresolvedException("d();", "b", 1, 0);
+        assertMethods();
+        assertActiveKeys();
+    }
+
+    public void testDropClassToMethod() {
+        PersistentSnippet c = classKey(assertEval("class C { int f() { return 7; } }"));
+        DeclarationSnippet m = methodKey(assertEval("int m() { return new C().f(); }"));
+        assertDrop(c,
+                ste(c, VALID, DROPPED, true, null),
+                ste(m, VALID, RECOVERABLE_DEFINED, false, c));
+        assertUnresolvedDependencies1(m, RECOVERABLE_DEFINED, "class C");
+        assertEvalUnresolvedException("m();", "m", 1, 0);
+        assertActiveKeys();
+    }
+
+    public void testDropVarToClass() {
+        PersistentSnippet x = varKey(assertEval("int x;"));
+        DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x; }"));
+        assertDrop(x,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(x, VALID, DROPPED, true, null),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, x));
+        assertUnresolvedDependencies1(a, RECOVERABLE_NOT_DEFINED, "variable x");
+        assertDeclareFail("new A().a;", "compiler.err.cant.resolve.location");
+        assertVariables();
+        assertActiveKeys();
+    }
+
+    public void testDropMethodToClass() {
+        PersistentSnippet x = methodKey(assertEval("int x() { return 0; }"));
+        DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x(); }"));
+        assertDrop(x,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(x, VALID, DROPPED, true, null),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, x));
+        assertUnresolvedDependencies1(a, RECOVERABLE_NOT_DEFINED, "method x()");
+        assertDeclareFail("new A().a;", "compiler.err.cant.resolve.location");
+        assertMethods();
+        assertActiveKeys();
+    }
+
+    public void testDropClassToClass() {
+        PersistentSnippet a = classKey(assertEval("class A {}"));
+        PersistentSnippet b = classKey(assertEval("class B extends A {}"));
+        PersistentSnippet c = classKey(assertEval("class C extends B {}"));
+        PersistentSnippet d = classKey(assertEval("class D extends C {}"));
+        assertDrop(a,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(a, VALID, DROPPED, true, null),
+                ste(b, VALID, RECOVERABLE_NOT_DEFINED, true, a),
+                ste(c, VALID, RECOVERABLE_NOT_DEFINED, true, b),
+                ste(d, VALID, RECOVERABLE_NOT_DEFINED, true, c));
+        assertUnresolvedDependencies1((DeclarationSnippet) b, RECOVERABLE_NOT_DEFINED, "class A");
+        assertDrop(c,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(c, RECOVERABLE_NOT_DEFINED, DROPPED, false, null),
+                ste(d, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, c));
+        assertEval("interface A {}", null, null,
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_ERROR,
+                ste(a, DROPPED, VALID, true, null),
+                ste(b, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, MAIN_SNIPPET));
+        assertClasses();
+        assertActiveKeys();
+    }
+
+    public void testDropNoUpdate() {
+        String as1 = "class A {}";
+        String as2 = "class A extends java.util.ArrayList<Boolean> {}";
+        PersistentSnippet a = classKey(assertEval(as1, added(VALID)));
+        PersistentSnippet b = classKey(assertEval("class B extends A {}", added(VALID)));
+        PersistentSnippet ax = classKey(assertEval(as2,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(b, VALID, VALID, true, MAIN_SNIPPET)));
+        ax = classKey(assertEval(as1,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(ax, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(b, VALID, VALID, true, MAIN_SNIPPET)));
+        assertDrop(b,
+                ste(b, VALID, DROPPED, true, null));
+        ax = classKey(assertEval(as2,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(ax, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertEval(as1,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(ax, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+    }
+}
diff --git a/langtools/test/jdk/jshell/EditorPadTest.java b/langtools/test/jdk/jshell/EditorPadTest.java
new file mode 100644
index 0000000..fd3b8e1
--- /dev/null
+++ b/langtools/test/jdk/jshell/EditorPadTest.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Testing built-in editor.
+ * @ignore 8139872
+ * @build ReplToolTesting EditorTestBase
+ * @run testng EditorPadTest
+ */
+
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.function.Consumer;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JViewport;
+import javax.swing.SwingUtilities;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class EditorPadTest extends EditorTestBase {
+
+    private static final int DELAY = 500;
+
+    private static Robot robot;
+    private static JFrame frame = null;
+    private static JTextArea area = null;
+    private static JButton cancel = null;
+    private static JButton accept = null;
+    private static JButton exit = null;
+
+    @BeforeClass
+    public static void setUp() {
+        try {
+            robot = new Robot();
+            robot.setAutoWaitForIdle(true);
+            robot.setAutoDelay(DELAY);
+        } catch (AWTException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    @AfterClass
+    public static void shutdown() {
+        executorShutdown();
+    }
+
+    @Override
+    public void writeSource(String s) {
+        SwingUtilities.invokeLater(() -> area.setText(s));
+    }
+
+    @Override
+    public String getSource() {
+        try {
+            String[] s = new String[1];
+            SwingUtilities.invokeAndWait(() -> s[0] = area.getText());
+            return s[0];
+        } catch (InvocationTargetException | InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void accept() {
+        clickOn(accept);
+    }
+
+    @Override
+    public void exit() {
+        clickOn(exit);
+    }
+
+    @Override
+    public void cancel() {
+        clickOn(cancel);
+    }
+
+    @Override
+    public void shutdownEditor() {
+        SwingUtilities.invokeLater(this::clearElements);
+        waitForIdle();
+    }
+
+    @Test
+    public void testShuttingDown() {
+        testEditor(
+                (a) -> assertEditOutput(a, "/e", "", this::shutdownEditor)
+        );
+    }
+
+    private void waitForIdle() {
+        robot.waitForIdle();
+        robot.delay(DELAY);
+    }
+
+    private Future<?> task;
+    @Override
+    public void assertEdit(boolean after, String cmd,
+                           Consumer<String> checkInput, Consumer<String> checkOutput, Action action) {
+        if (!after) {
+            setCommandInput(cmd + "\n");
+            task = getExecutor().submit(() -> {
+                try {
+                    waitForIdle();
+                    SwingUtilities.invokeLater(this::seekElements);
+                    waitForIdle();
+                    checkInput.accept(getSource());
+                    action.accept();
+                } catch (Throwable e) {
+                    shutdownEditor();
+                    if (e instanceof AssertionError) {
+                        throw (AssertionError) e;
+                    }
+                    throw new RuntimeException(e);
+                }
+            });
+        } else {
+            try {
+                task.get();
+                waitForIdle();
+                checkOutput.accept(getCommandOutput());
+            } catch (ExecutionException e) {
+                if (e.getCause() instanceof AssertionError) {
+                    throw (AssertionError) e.getCause();
+                }
+                throw new RuntimeException(e);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            } finally {
+                shutdownEditor();
+            }
+        }
+    }
+
+    private void seekElements() {
+        for (Frame f : Frame.getFrames()) {
+            if (f.getTitle().contains("Edit Pad")) {
+                frame = (JFrame) f;
+                // workaround
+                frame.setLocation(0, 0);
+                Container root = frame.getContentPane();
+                for (Component c : root.getComponents()) {
+                    if (c instanceof JScrollPane) {
+                        JScrollPane scrollPane = (JScrollPane) c;
+                        for (Component comp : scrollPane.getComponents()) {
+                            if (comp instanceof JViewport) {
+                                JViewport view = (JViewport) comp;
+                                area = (JTextArea) view.getComponent(0);
+                            }
+                        }
+                    }
+                    if (c instanceof JPanel) {
+                        JPanel p = (JPanel) c;
+                        for (Component comp : p.getComponents()) {
+                            if (comp instanceof JButton) {
+                                JButton b = (JButton) comp;
+                                switch (b.getText()) {
+                                    case "Cancel":
+                                        cancel = b;
+                                        break;
+                                    case "Exit":
+                                        exit = b;
+                                        break;
+                                    case "Accept":
+                                        accept = b;
+                                        break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private void clearElements() {
+        if (frame != null) {
+            frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
+            frame = null;
+        }
+        area = null;
+        accept = null;
+        cancel = null;
+        exit = null;
+    }
+
+    private void clickOn(JButton button) {
+        waitForIdle();
+        Point p = button.getLocationOnScreen();
+        Dimension d = button.getSize();
+        robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+    }
+}
diff --git a/langtools/test/jdk/jshell/EditorTestBase.java b/langtools/test/jdk/jshell/EditorTestBase.java
new file mode 100644
index 0000000..182d265
--- /dev/null
+++ b/langtools/test/jdk/jshell/EditorTestBase.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public abstract class EditorTestBase extends ReplToolTesting {
+
+    private static ExecutorService executor;
+
+    public abstract void writeSource(String s);
+    public abstract String getSource();
+    public abstract void accept();
+    public abstract void exit();
+    public abstract void cancel();
+    public abstract void shutdownEditor();
+
+    public void testEditor(ReplTest... tests) {
+        testEditor(false, new String[]{"-nostartup"}, tests);
+    }
+
+    public void testEditor(boolean defaultStartup, String[] args, ReplTest... tests) {
+        test(defaultStartup, args, tests);
+    }
+
+    public abstract void assertEdit(boolean after, String cmd,
+                                    Consumer<String> checkInput, Consumer<String> checkOutput, Action action);
+
+    public void assertEditInput(boolean after, String cmd, Consumer<String> checkInput, Action action) {
+        assertEdit(after, cmd, checkInput, s -> {}, action);
+    }
+
+    public void assertEditOutput(boolean after, String cmd, Consumer<String> checkOutput, Action action) {
+        assertEdit(after, cmd, s -> {}, checkOutput, action);
+    }
+
+    public void assertEditInput(boolean after, String cmd, String input, Action action) {
+        assertEditInput(after, cmd, s -> assertEquals(s, input, "Input"), action);
+    }
+
+    public void assertEditOutput(boolean after, String cmd, String output, Action action) {
+        assertEditOutput(after, cmd, s -> assertEquals(s, output, "command"), action);
+    }
+
+    @Test
+    public void testEditNegative() {
+        for (String edit : new String[] {"/e", "/edit"}) {
+            test(new String[]{"-nostartup"},
+                    a -> assertCommand(a, edit + " 1",
+                            "|  No definition or id named 1 found.  See /classes /methods /vars or /list\n"),
+                    a -> assertCommand(a, edit + " -1",
+                            "|  No definition or id named -1 found.  See /classes /methods /vars or /list\n"),
+                    a -> assertCommand(a, edit + " unknown",
+                            "|  No definition or id named unknown found.  See /classes /methods /vars or /list\n")
+            );
+        }
+    }
+
+    @Test
+    public void testDoNothing() {
+        testEditor(
+                a -> assertVariable(a, "int", "a", "0", "0"),
+                a -> assertEditOutput(a, "/e 1", "", this::exit),
+                a -> assertCommandCheckOutput(a, "/v", assertVariables())
+        );
+    }
+
+    @Test
+    public void testEditVariable1() {
+        testEditor(
+                a -> assertVariable(a, "int", "a", "0", "0"),
+                a -> assertEditOutput(a, "/e 1", "|  Modified variable a of type int with initial value 10\n", () -> {
+                    writeSource("\n\n\nint a = 10;\n\n\n");
+                    exit();
+                    loadVariable(true, "int", "a", "10", "10");
+                }),
+                a -> assertEditOutput(a, "/e 1", "|  Modified variable a of type int with initial value 15\n", () -> {
+                    writeSource("int a = 15;");
+                    exit();
+                    loadVariable(true, "int", "a", "15", "15");
+                }),
+                a -> assertCommandCheckOutput(a, "/v", assertVariables())
+        );
+    }
+
+    @Test
+    public void testEditVariable2() {
+        testEditor(
+                a -> assertVariable(a, "int", "a", "0", "0"),
+                a -> assertEditOutput(a, "/e 1", "|  Added variable b of type int with initial value 10\n", () -> {
+                    writeSource("int b = 10;");
+                    exit();
+                    loadVariable(true, "int", "b", "10", "10");
+                }),
+                a -> assertEditOutput(a, "/e 1", "|  Modified variable a of type int with initial value 15\n", () -> {
+                    writeSource("int a = 15;");
+                    exit();
+                    loadVariable(true, "int", "a", "15", "15");
+                }),
+                a -> assertCommandCheckOutput(a, "/v", assertVariables())
+        );
+    }
+
+    @Test
+    public void testEditClass1() {
+        testEditor(
+                a -> assertClass(a, "class A {}", "class", "A"),
+                a -> assertEditOutput(a, "/e 1", "", () -> {
+                    writeSource("\n\n\nclass A {}\n\n\n");
+                    exit();
+                    loadClass(true, "class A {}", "class", "A");
+                }),
+                a -> assertEditOutput(a, "/e 1",
+                        "|  Replaced enum A\n" +
+                        "|    Update overwrote class A\n", () -> {
+                    writeSource("enum A {}");
+                    exit();
+                    loadClass(true, "enum A {}", "enum", "A");
+                }),
+                a -> assertCommandCheckOutput(a, "/c", assertClasses())
+        );
+    }
+
+    @Test
+    public void testEditClass2() {
+        testEditor(
+                a -> assertClass(a, "class A {}", "class", "A"),
+                a -> assertEditOutput(a, "/e 1", "|  Added class B\n", () -> {
+                    writeSource("class B { }");
+                    exit();
+                    loadClass(true, "class B {}", "class", "B");
+                }),
+                a -> assertEditOutput(a, "/e 1",
+                        "|  Replaced enum A\n" +
+                        "|    Update overwrote class A\n", () -> {
+                    writeSource("enum A {}");
+                    exit();
+                    loadClass(true, "enum A {}", "enum", "A");
+                }),
+                a -> assertCommandCheckOutput(a, "/c", assertClasses())
+        );
+    }
+
+    @Test
+    public void testEditMethod1() {
+        testEditor(
+                a -> assertMethod(a, "void f() {}", "()void", "f"),
+                a -> assertEditOutput(a, "/e 1", "", () -> {
+                    writeSource("\n\n\nvoid f() {}\n\n\n");
+                    exit();
+                    loadMethod(true, "void f() {}", "()void", "f");
+                }),
+                a -> assertEditOutput(a, "/e 1",
+                        "|  Replaced method f()\n" +
+                        "|    Update overwrote method f()\n", () -> {
+                    writeSource("double f() { return 0; }");
+                    exit();
+                    loadMethod(true, "double f() { return 0; }", "()double", "f");
+                }),
+                a -> assertCommandCheckOutput(a, "/m", assertMethods())
+        );
+    }
+
+    @Test
+    public void testEditMethod2() {
+        testEditor(
+                a -> assertMethod(a, "void f() {}", "()void", "f"),
+                a -> assertEditOutput(a, "/e 1", "|  Added method g()\n", () -> {
+                    writeSource("void g() {}");
+                    exit();
+                    loadMethod(true, "void g() {}", "()void", "g");
+                }),
+                a -> assertEditOutput(a, "/e 1",
+                        "|  Replaced method f()\n" +
+                        "|    Update overwrote method f()\n", () -> {
+                    writeSource("double f() { return 0; }");
+                    exit();
+                    loadMethod(true, "double f() { return 0; }", "()double", "f");
+                }),
+                a -> assertCommandCheckOutput(a, "/m", assertMethods())
+        );
+    }
+
+    @Test
+    public void testNoArguments() {
+        testEditor(
+                a -> assertVariable(a, "int", "a"),
+                a -> assertMethod(a, "void f() {}", "()void", "f"),
+                a -> assertClass(a, "class A {}", "class", "A"),
+                a -> assertEditInput(a, "/e", s -> {
+                    String[] ss = s.split("\n");
+                    assertEquals(ss.length, 3, "Expected 3 lines: " + s);
+                    assertEquals(ss[0], "int a;");
+                    assertEquals(ss[1], "void f() {}");
+                    assertEquals(ss[2], "class A {}");
+                }, this::exit)
+        );
+    }
+
+    @Test
+    public void testStartup() {
+        testEditor(true, new String[0],
+                a -> assertEditInput(a, "/e", s -> assertTrue(s.isEmpty(), "Checking of startup: " + s), this::cancel),
+                a -> assertEditInput(a, "/e printf", assertStartsWith("void printf"), this::cancel));
+    }
+
+    @Test
+    public void testCancel() {
+        testEditor(
+                a -> assertVariable(a, "int", "a"),
+                a -> assertEditOutput(a, "/e a", "", () -> {
+                    writeSource("int b = 10");
+                    cancel();
+                })
+        );
+    }
+
+    @Test
+    public void testAccept() {
+        testEditor(
+                a -> assertVariable(a, "int", "a"),
+                a -> assertEditOutput(a, "/e a", "|  Added variable b of type int with initial value 10\n", () -> {
+                    writeSource("int b = 10");
+                    accept();
+                    exit();
+                })
+        );
+    }
+
+    public static ExecutorService getExecutor() {
+        if (executor == null) {
+            executor = Executors.newSingleThreadExecutor();
+        }
+        return executor;
+    }
+
+    public static void executorShutdown() {
+        if (executor != null) {
+            executor.shutdown();
+            executor = null;
+        }
+    }
+
+    interface Action {
+        void accept();
+    }
+}
diff --git a/langtools/test/jdk/jshell/EmptyTest.java b/langtools/test/jdk/jshell/EmptyTest.java
new file mode 100644
index 0000000..6e83843
--- /dev/null
+++ b/langtools/test/jdk/jshell/EmptyTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 null test
+ * @build KullaTesting TestingInputStream
+ * @run testng EmptyTest
+ */
+
+import org.testng.annotations.Test;
+
+@Test
+public class EmptyTest extends KullaTesting {
+
+    public void testEmpty() {
+        assertEvalEmpty("");
+    }
+
+    public void testSpace() {
+        assertEvalEmpty("    ");
+    }
+
+    public void testSemicolon() {
+        assertEval(";", "");
+    }
+
+    public void testSlashStarComment() {
+        assertEvalEmpty("/*test*/");
+    }
+
+    public void testSlashStarCommentSemicolon() {
+        assertEval("/*test*/;", "");
+    }
+
+    public void testSlashComment() {
+        assertEvalEmpty("// test");
+    }
+}
diff --git a/langtools/test/jdk/jshell/ErrorTranslationTest.java b/langtools/test/jdk/jshell/ErrorTranslationTest.java
new file mode 100644
index 0000000..7ed072e
--- /dev/null
+++ b/langtools/test/jdk/jshell/ErrorTranslationTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for shell error translation
+ * @library /tools/lib
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic ToolBox Compiler
+ * @run testng ErrorTranslationTest
+ */
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+import javax.tools.Diagnostic;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ErrorTranslationTest extends ReplToolTesting {
+
+    @Test(enabled = false) // TODO 8080353
+    public void testErrors() {
+        test(
+                a -> assertDiagnostic(a, "abstract void f();", newExpectedDiagnostic(0, 8, 0, -1, -1, Diagnostic.Kind.ERROR)),
+                a -> assertDiagnostic(a, "native void f();", newExpectedDiagnostic(0, 6, 0, -1, -1, Diagnostic.Kind.ERROR)),
+                a -> assertDiagnostic(a, "static void f();", newExpectedDiagnostic(0, 16, 0, -1, -1, Diagnostic.Kind.ERROR)),
+                a -> assertDiagnostic(a, "synchronized void f();", newExpectedDiagnostic(0, 12, 0, -1, -1, Diagnostic.Kind.ERROR)),
+                a -> assertDiagnostic(a, "default void f();", newExpectedDiagnostic(0, 7, 0, -1, -1, Diagnostic.Kind.ERROR))
+        );
+    }
+
+    public void testWarnings() {
+        List<ReplTest> list = new ArrayList<>();
+        ExpectedDiagnostic[] diagnostics = new ExpectedDiagnostic[]{
+                newExpectedDiagnostic(0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
+                newExpectedDiagnostic(0, 9, 0, -1, -1, Diagnostic.Kind.WARNING),
+                newExpectedDiagnostic(0, 7, 0, -1, -1, Diagnostic.Kind.WARNING),
+                newExpectedDiagnostic(0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
+                newExpectedDiagnostic(0, 5, 0, -1, -1, Diagnostic.Kind.WARNING)};
+        String[] mods = {"public", "protected", "private", "static", "final"};
+        for (int i = 0; i < mods.length; ++i) {
+            for (String code : new String[] {"class A {}", "void f() {}", "int a;"}) {
+                final int finalI = i;
+                list.add(a -> assertDiagnostic(a, mods[finalI] + " " + code, diagnostics[finalI]));
+            }
+        }
+        test(list.toArray(new ReplTest[list.size()]));
+    }
+
+    @Test(enabled = false) // TODO 8132147
+    public void stressTest() {
+        Compiler compiler = new Compiler();
+        Path oome = compiler.getPath("OOME.repl");
+        Path soe = compiler.getPath("SOE.repl");
+        compiler.writeToFile(oome,
+                "List<byte[]> list = new ArrayList<>();\n",
+                "while (true) {\n" +
+                "   list.add(new byte[1000000]);\n" +
+                "}");
+        compiler.writeToFile(soe,
+                "void f() { f(); }",
+                "f();");
+        List<ReplTest> tests = new ArrayList<>();
+        for (int i = 0; i < 25; ++i) {
+            tests.add(a -> assertCommandCheckOutput(a, "/o " + soe.toString(),
+                    assertStartsWith("|  java.lang.StackOverflowError thrown")));
+            tests.add(a -> assertCommandCheckOutput(a, "/o " + oome.toString(),
+                    assertStartsWith("|  java.lang.OutOfMemoryError thrown: Java heap space")));
+        }
+        test(tests.toArray(new ReplTest[tests.size()]));
+    }
+
+    private ExpectedDiagnostic newExpectedDiagnostic(long startPosition, long endPosition, long position,
+                                                     long lineNumber, long columnNumber, Diagnostic.Kind kind) {
+        return new ExpectedDiagnostic("", startPosition, endPosition, position, lineNumber, columnNumber, kind);
+    }
+
+    private void assertDiagnostic(boolean after, String cmd, ExpectedDiagnostic expectedDiagnostic) {
+        assertCommandCheckOutput(after, cmd, assertDiagnostic(cmd, expectedDiagnostic));
+    }
+
+    private Consumer<String> assertDiagnostic(String expectedSource, ExpectedDiagnostic expectedDiagnostic) {
+        int start = (int) expectedDiagnostic.getStartPosition();
+        int end = (int) expectedDiagnostic.getEndPosition();
+        String expectedMarkingLine = createMarkingLine(start, end);
+        return s -> {
+            String[] lines = s.split("\n");
+            if (lines.length <= 3) {
+                throw new AssertionError("Not enough lines: " + s);
+            }
+            String kind = getKind(expectedDiagnostic.getKind());
+            assertEquals(lines[0], kind);
+            String source;
+            String markingLine;
+            switch (expectedDiagnostic.getKind()) {
+                case ERROR:
+                case WARNING:
+                    source = lines[2];
+                    markingLine = lines[3];
+                    break;
+                default:
+                    throw new AssertionError("Unsupported diagnostic kind: " + expectedDiagnostic.getKind());
+            }
+            assertTrue(source.endsWith(expectedSource), "Expected: " + expectedSource + ", found: " + source);
+            assertEquals(markingLine, expectedMarkingLine, "Input: " + expectedSource + ", marking line: ");
+        };
+    }
+
+    private String createMarkingLine(int start, int end) {
+        assertTrue(end >= start, String.format("End position %d is less than start position %d", end, start));
+        StringBuilder sb = new StringBuilder();
+        sb.append("|  ");
+        for (int i = 0; i < start; ++i) {
+            sb.append(' ');
+        }
+        sb.append('^');
+        for (int i = 1; i < end - start - 1; ++i) {
+            sb.append('-');
+        }
+        if (start < end) {
+            sb.append('^');
+        }
+        return sb.toString();
+    }
+
+    public String getKind(Diagnostic.Kind kind) {
+        switch (kind) {
+            case WARNING:
+                return "|  Warning:";
+            case ERROR:
+                return "|  Error:";
+            default:
+                throw new AssertionError("Unsupported kind: " + kind);
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/ExceptionsTest.java b/langtools/test/jdk/jshell/ExceptionsTest.java
new file mode 100644
index 0000000..a5dde23
--- /dev/null
+++ b/langtools/test/jdk/jshell/ExceptionsTest.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for exceptions
+ * @build KullaTesting TestingInputStream
+ * @run testng ExceptionsTest
+ */
+
+import jdk.jshell.SnippetEvent;
+import jdk.jshell.EvalException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import jdk.jshell.Snippet;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+@Test
+public class ExceptionsTest extends KullaTesting {
+
+    public void throwUncheckedException() {
+        String message = "error_message";
+        SnippetEvent cr = assertEvalException("throw new RuntimeException(\"" + message + "\");");
+        assertExceptionMatch(cr,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("", "", cr.snippet(), 1)));
+    }
+
+    public void throwCheckedException() {
+        String message = "error_message";
+        SnippetEvent cr = assertEvalException("throw new Exception(\"" + message + "\");");
+        assertExceptionMatch(cr,
+                new ExceptionInfo(Exception.class, message,
+                        newStackTraceElement("", "", cr.snippet(), 1)));
+    }
+
+    public void throwFromStaticMethodOfClass() {
+        String message = "error_message";
+        Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+        Snippet s2 = classKey(assertEval("class A { static void g() { f(); } }"));
+        SnippetEvent cr3 = assertEvalException("A.g();");
+        assertExceptionMatch(cr3,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("", "f", s1, 1),
+                        newStackTraceElement("A", "g", s2, 1),
+                        newStackTraceElement("", "", cr3.snippet(), 1)));
+    }
+
+    public void throwFromStaticMethodOfInterface() {
+        String message = "error_message";
+        Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+        Snippet s2 = classKey(assertEval("interface A { static void g() { f(); } }"));
+        SnippetEvent cr3 = assertEvalException("A.g();");
+        assertExceptionMatch(cr3,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("", "f", s1, 1),
+                        newStackTraceElement("A", "g", s2, 1),
+                        newStackTraceElement("", "", cr3.snippet(), 1)));
+    }
+
+    public void throwFromConstructor() {
+        String message = "error_message";
+        Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+        Snippet s2 = classKey(assertEval("class A { A() { f(); } }"));
+        SnippetEvent cr3 = assertEvalException("new A();");
+        assertExceptionMatch(cr3,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("", "f", s1, 1),
+                        newStackTraceElement("A", "<init>", s2, 1),
+                        newStackTraceElement("", "", cr3.snippet(), 1)));
+    }
+
+    public void throwFromDefaultMethodOfInterface() {
+        String message = "error_message";
+        Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }"));
+        Snippet s2 = classKey(assertEval("interface A { default void g() { f(); } }"));
+        SnippetEvent cr3 = assertEvalException("new A() { }.g();");
+        assertExceptionMatch(cr3,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("", "f", s1, 1),
+                        newStackTraceElement("A", "g", s2, 1),
+                        newStackTraceElement("", "", cr3.snippet(), 1)));
+    }
+
+    public void throwFromLambda() {
+        String message = "lambda";
+        Snippet s1 = varKey(assertEval(
+                "Runnable run = () -> {\n" +
+                "   throw new RuntimeException(\"" + message + "\");\n" +
+                "};"
+        ));
+        SnippetEvent cr2 = assertEvalException("run.run();");
+        assertExceptionMatch(cr2,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("", "lambda$", s1, 2),
+                        newStackTraceElement("", "", cr2.snippet(), 1)));
+    }
+
+    public void throwFromAnonymousClass() {
+        String message = "anonymous";
+        Snippet s1 = varKey(assertEval(
+                "Runnable run = new Runnable() {\n" +
+                "   public void run() {\n"+
+                "       throw new RuntimeException(\"" + message + "\");\n" +
+                "   }\n" +
+                "};"
+        ));
+        SnippetEvent cr2 = assertEvalException("run.run();");
+        assertExceptionMatch(cr2,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("1", "run", s1, 3),
+                        newStackTraceElement("", "", cr2.snippet(), 1)));
+    }
+
+    public void throwFromLocalClass() {
+        String message = "local";
+        Snippet s1 = methodKey(assertEval(
+                "void f() {\n" +
+                "   class A {\n" +
+                "       void f() {\n"+
+                "           throw new RuntimeException(\"" + message + "\");\n" +
+                "       }\n" +
+                "   }\n" +
+                "   new A().f();\n" +
+                "}"
+        ));
+        SnippetEvent cr2 = assertEvalException("f();");
+        assertExceptionMatch(cr2,
+                new ExceptionInfo(RuntimeException.class, message,
+                        newStackTraceElement("1A", "f", s1, 4),
+                        newStackTraceElement("", "f", s1, 7),
+                        newStackTraceElement("", "", cr2.snippet(), 1)));
+    }
+
+    @Test(enabled = false) // TODO 8129427
+    public void outOfMemory() {
+        assertEval("import java.util.*;");
+        assertEval("List<byte[]> list = new ArrayList<>();");
+        assertExecuteException("while (true) { list.add(new byte[10000]); }", OutOfMemoryError.class);
+    }
+
+    public void stackOverflow() {
+        assertEval("void f() { f(); }");
+        assertExecuteException("f();", StackOverflowError.class);
+    }
+
+    private StackTraceElement newStackTraceElement(String className, String methodName, Snippet key, int lineNumber) {
+        return new StackTraceElement(className, methodName, "#" + key.id(), lineNumber);
+    }
+
+    private static class ExceptionInfo {
+        public final Class<? extends Throwable> exception;
+        public final String message;
+        public final StackTraceElement[] stackTraceElements;
+
+        public ExceptionInfo(Class<? extends Throwable> exception, String message, StackTraceElement...stackTraceElements) {
+            this.exception = exception;
+            this.message = message;
+            this.stackTraceElements = stackTraceElements.length == 0 ? null : stackTraceElements;
+        }
+    }
+
+    private void assertExecuteException(String input, Class<? extends Throwable> exception) {
+        assertExceptionMatch(assertEvalException(input), new ExceptionInfo(exception, null));
+    }
+
+    private void assertExceptionMatch(SnippetEvent cr, ExceptionInfo exceptionInfo) {
+        assertNotNull(cr.exception(), "Expected exception was not thrown: " + exceptionInfo.exception);
+        if (cr.exception() instanceof EvalException) {
+            EvalException ex = (EvalException) cr.exception();
+            String actualException = ex.getExceptionClassName();
+            String expectedException = exceptionInfo.exception.getCanonicalName();
+            String stackTrace = getStackTrace(ex);
+            String source = cr.snippet().source();
+            assertEquals(actualException, expectedException,
+                    String.format("Given \"%s\" expected exception: %s, got: %s%nStack trace:%n%s",
+                            source, expectedException, actualException, stackTrace));
+            if (exceptionInfo.message != null) {
+                assertEquals(ex.getMessage(), exceptionInfo.message,
+                        String.format("Given \"%s\" expected message: %s, got: %s",
+                                source, exceptionInfo.message, ex.getMessage()));
+            }
+            if (exceptionInfo.stackTraceElements != null) {
+                assertStackTrace(ex.getStackTrace(), exceptionInfo.stackTraceElements,
+                        String.format("Given \"%s\"%nStack trace:%n%s%n",
+                                source, stackTrace));
+            }
+        } else {
+            fail("Unexpected execution exceptionInfo: " + cr.exception());
+        }
+    }
+
+    private void assertStackTrace(StackTraceElement[] actual, StackTraceElement[] expected, String message) {
+        if (actual != expected) {
+            if (actual == null || expected == null) {
+                fail(message);
+            } else {
+                assertEquals(actual.length, expected.length, message + " : arrays do not have the same size");
+                for (int i = 0; i < actual.length; ++i) {
+                    StackTraceElement actualElement = actual[i];
+                    StackTraceElement expectedElement = expected[i];
+                    assertEquals(actualElement.getClassName(), expectedElement.getClassName(), message + " : class names");
+                    String expectedMethodName = expectedElement.getMethodName();
+                    if (expectedMethodName.startsWith("lambda$")) {
+                        assertTrue(actualElement.getMethodName().startsWith("lambda$"), message + " : method names");
+                    } else {
+                        assertEquals(actualElement.getMethodName(), expectedElement.getMethodName(), message + " : method names");
+                    }
+                    assertEquals(actualElement.getFileName(), expectedElement.getFileName(), message + " : file names");
+                    assertEquals(actualElement.getLineNumber(), expectedElement.getLineNumber(), message + " : line numbers");
+                }
+            }
+        }
+    }
+
+    private String getStackTrace(EvalException ex) {
+        StringWriter st = new StringWriter();
+        ex.printStackTrace(new PrintWriter(st));
+        return st.toString();
+    }
+}
diff --git a/langtools/test/jdk/jshell/ExpectedDiagnostic.java b/langtools/test/jdk/jshell/ExpectedDiagnostic.java
new file mode 100644
index 0000000..2416c98
--- /dev/null
+++ b/langtools/test/jdk/jshell/ExpectedDiagnostic.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Diag;
+import static org.testng.Assert.assertEquals;
+
+public class ExpectedDiagnostic {
+
+    private final String code;
+    private final long startPosition;
+    private final long endPosition;
+    private final long position;
+    private final long lineNumber;
+    private final long columnNumber;
+    private final Diagnostic.Kind kind;
+
+    public ExpectedDiagnostic(
+            String code, long startPosition, long endPosition,
+            long position, long lineNumber, long columnNumber,
+            Diagnostic.Kind kind) {
+        this.code = code;
+        this.startPosition = startPosition;
+        this.endPosition = endPosition;
+        this.position = position;
+        this.lineNumber = lineNumber;
+        this.columnNumber = columnNumber;
+        this.kind = kind;
+    }
+
+    public long getStartPosition() {
+        return startPosition;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public long getEndPosition() {
+        return endPosition;
+    }
+
+    public long getPosition() {
+        return position;
+    }
+
+    public long getLineNumber() {
+        return lineNumber;
+    }
+
+    public long getColumnNumber() {
+        return columnNumber;
+    }
+
+    public Diagnostic.Kind getKind() {
+        return kind;
+    }
+
+    public void assertDiagnostic(Diag diagnostic) {
+        String code = diagnostic.getCode();
+        assertEquals(code, this.code, "Expected error: " + this.code + ", got: " + code);
+        assertEquals(diagnostic.isError(), kind == Diagnostic.Kind.ERROR);
+        if (startPosition != -1) {
+            assertEquals(diagnostic.getStartPosition(), startPosition, "Start position");
+        }
+        if (endPosition != -1) {
+            assertEquals(diagnostic.getEndPosition(), endPosition, "End position");
+        }
+        if (position != -1) {
+            assertEquals(diagnostic.getPosition(), position, "Position");
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/ExternalEditorTest.java b/langtools/test/jdk/jshell/ExternalEditorTest.java
new file mode 100644
index 0000000..b337c3d
--- /dev/null
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Testing external editor.
+ * @bug 8080843
+ * @ignore 8080843
+ * @build ReplToolTesting CustomEditor EditorTestBase
+ * @run testng ExternalEditorTest
+ */
+
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.function.Consumer;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+public class ExternalEditorTest extends EditorTestBase {
+
+    private static Path executionScript;
+    private static ServerSocket listener;
+
+    private DataInputStream inputStream;
+    private DataOutputStream outputStream;
+
+    @Override
+    public void writeSource(String s) {
+        try {
+            outputStream.writeInt(CustomEditor.SOURCE_CODE);
+            byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
+            outputStream.writeInt(bytes.length);
+            outputStream.write(bytes);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public String getSource() {
+        try {
+            outputStream.writeInt(CustomEditor.GET_SOURCE_CODE);
+            int length = inputStream.readInt();
+            byte[] bytes = new byte[length];
+            inputStream.readFully(bytes);
+            return new String(bytes, StandardCharsets.UTF_8);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    private void sendCode(int code) {
+        try {
+            outputStream.writeInt(code);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void accept() {
+        sendCode(CustomEditor.ACCEPT_CODE);
+    }
+
+    @Override
+    public void exit() {
+        sendCode(CustomEditor.EXIT_CODE);
+        inputStream = null;
+        outputStream = null;
+    }
+
+    @Override
+    public void cancel() {
+        sendCode(CustomEditor.CANCEL_CODE);
+    }
+
+    @Override
+    public void testEditor(boolean defaultStartup, String[] args, ReplTest... tests) {
+        ReplTest[] t = new ReplTest[tests.length + 1];
+        t[0] = a -> assertCommandCheckOutput(a, "/seteditor " + executionScript,
+                assertStartsWith("|  Editor set to: " + executionScript));
+        System.arraycopy(tests, 0, t, 1, tests.length);
+        super.testEditor(defaultStartup, args, t);
+    }
+
+    private static boolean isWindows() {
+        return System.getProperty("os.name").startsWith("Windows");
+    }
+
+    @BeforeClass
+    public static void setUp() throws IOException {
+        listener = new ServerSocket(0);
+        listener.setSoTimeout(30000);
+        int localPort = listener.getLocalPort();
+
+        executionScript = Paths.get(isWindows() ? "editor.bat" : "editor.sh").toAbsolutePath();
+        Path java = Paths.get(System.getProperty("java.home")).resolve("bin").resolve("java");
+        try (BufferedWriter writer = Files.newBufferedWriter(executionScript)) {
+            if(!isWindows()) {
+                writer.append(java.toString()).append(" ")
+                        .append(" -cp ").append(System.getProperty("java.class.path"))
+                        .append(" CustomEditor ").append(Integer.toString(localPort)).append(" $@");
+                executionScript.toFile().setExecutable(true);
+            } else {
+                writer.append(java.toString()).append(" ")
+                        .append(" -cp ").append(System.getProperty("java.class.path"))
+                        .append(" CustomEditor ").append(Integer.toString(localPort)).append(" %*");
+            }
+        }
+    }
+
+    private Future<?> task;
+    @Override
+    public void assertEdit(boolean after, String cmd,
+                           Consumer<String> checkInput, Consumer<String> checkOutput, Action action) {
+        if (!after) {
+            setCommandInput(cmd + "\n");
+            task = getExecutor().submit(() -> {
+                try (Socket socket = listener.accept()) {
+                    inputStream = new DataInputStream(socket.getInputStream());
+                    outputStream = new DataOutputStream(socket.getOutputStream());
+                    checkInput.accept(getSource());
+                    action.accept();
+                } catch (SocketTimeoutException e) {
+                    fail("Socket timeout exception.\n Output: " + getCommandOutput() +
+                            "\n, error: " + getCommandErrorOutput());
+                } catch (Throwable e) {
+                    shutdownEditor();
+                    if (e instanceof AssertionError) {
+                        throw (AssertionError) e;
+                    }
+                    throw new RuntimeException(e);
+                }
+            });
+        } else {
+            try {
+                task.get();
+                checkOutput.accept(getCommandOutput());
+            } catch (ExecutionException e) {
+                if (e.getCause() instanceof AssertionError) {
+                    throw (AssertionError) e.getCause();
+                }
+                throw new RuntimeException(e);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Override
+    public void shutdownEditor() {
+        if (outputStream != null) {
+            exit();
+        }
+    }
+
+    @Test
+    public void setUnknownEditor() {
+        test(
+                a -> assertCommand(a, "/seteditor", "|  /seteditor requires a path argument\n"),
+                a -> assertCommand(a, "/seteditor UNKNOWN", "|  Editor set to: UNKNOWN\n"),
+                a -> assertCommand(a, "int a;", null),
+                a -> assertCommand(a, "/e 1",
+                        "|  Edit Error: process IO failure: Cannot run program \"UNKNOWN\": error=2, No such file or directory\n")
+        );
+    }
+
+    @Test(enabled = false)
+    public void testRemoveTempFile() {
+        test(new String[]{"-nostartup"},
+                a -> assertCommandCheckOutput(a, "/seteditor " + executionScript,
+                        assertStartsWith("|  Editor set to: " + executionScript)),
+                a -> assertVariable(a, "int", "a", "0", "0"),
+                a -> assertEditOutput(a, "/e 1", assertStartsWith("|  Edit Error: Failure read edit file:"), () -> {
+                    sendCode(CustomEditor.REMOVE_CODE);
+                    exit();
+                }),
+                a -> assertCommandCheckOutput(a, "/v", assertVariables())
+        );
+    }
+
+    @AfterClass
+    public static void shutdown() throws IOException {
+        executorShutdown();
+        if (listener != null) {
+            listener.close();
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/HistoryTest.java b/langtools/test/jdk/jshell/HistoryTest.java
new file mode 100644
index 0000000..df6355a
--- /dev/null
+++ b/langtools/test/jdk/jshell/HistoryTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Completion
+ * @build HistoryTest
+ * @run testng HistoryTest
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.BackingStoreException;
+import jdk.internal.jline.console.history.MemoryHistory;
+
+import jdk.jshell.JShell;
+import jdk.jshell.SourceCodeAnalysis;
+import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
+import org.testng.annotations.Test;
+import jdk.internal.jshell.tool.EditingHistory;
+
+import static org.testng.Assert.*;
+
+@Test
+public class HistoryTest {
+
+    public void testHistory() {
+        JShell eval = JShell.builder()
+                .in(new ByteArrayInputStream(new byte[0]))
+                .out(new PrintStream(new ByteArrayOutputStream()))
+                .err(new PrintStream(new ByteArrayOutputStream()))
+                .build();
+        SourceCodeAnalysis analysis = eval.sourceCodeAnalysis();
+        MemoryPreferences prefs = new MemoryPreferences(null, "");
+        EditingHistory history = new EditingHistory(prefs) {
+            @Override protected CompletionInfo analyzeCompletion(String input) {
+                return analysis.analyzeCompletion(input);
+            }
+        };
+        history.add("void test() {");
+        history.add("    System.err.println(1);");
+        history.add("}");
+        history.add("/exit");
+
+        previousAndAssert(history, "/exit");
+
+        history.previous(); history.previous(); history.previous();
+
+        history.add("void test() { /*changed*/");
+
+        previousAndAssert(history, "}");
+        previousAndAssert(history, "    System.err.println(1);");
+        previousAndAssert(history, "void test() {");
+
+        assertFalse(history.previous());
+
+        nextAndAssert(history, "    System.err.println(1);");
+        nextAndAssert(history, "}");
+        nextAndAssert(history, "");
+
+        history.add("    System.err.println(2);");
+        history.add("} /*changed*/");
+
+        assertEquals(history.size(), 7);
+
+        history.save();
+
+        history = new EditingHistory(prefs) {
+            @Override protected CompletionInfo analyzeCompletion(String input) {
+                return analysis.analyzeCompletion(input);
+            }
+        };
+
+        previousSnippetAndAssert(history, "void test() { /*changed*/");
+        previousSnippetAndAssert(history, "/exit");
+        previousSnippetAndAssert(history, "void test() {");
+
+        assertFalse(history.previousSnippet());
+
+        nextSnippetAndAssert(history, "/exit");
+        nextSnippetAndAssert(history, "void test() { /*changed*/");
+        nextSnippetAndAssert(history, "");
+
+        assertFalse(history.nextSnippet());
+
+        history.add("{");
+        history.add("}");
+
+        history.save();
+
+        history = new EditingHistory(prefs) {
+            @Override protected CompletionInfo analyzeCompletion(String input) {
+                return analysis.analyzeCompletion(input);
+            }
+        };
+
+        previousSnippetAndAssert(history, "{");
+        previousSnippetAndAssert(history, "void test() { /*changed*/");
+        previousSnippetAndAssert(history, "/exit");
+        previousSnippetAndAssert(history, "void test() {");
+
+        while (history.next());
+
+        history.add("/*current1*/");
+        history.add("/*current2*/");
+        history.add("/*current3*/");
+
+        assertEquals(history.currentSessionEntries(), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/"));
+
+        history.remove(0);
+
+        assertEquals(history.currentSessionEntries(), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/"));
+
+        while (history.size() > 2)
+            history.remove(0);
+
+        assertEquals(history.currentSessionEntries(), Arrays.asList("/*current2*/", "/*current3*/"));
+
+        for (int i = 0; i < MemoryHistory.DEFAULT_MAX_SIZE * 2; i++) {
+            history.add("/exit");
+        }
+
+        history.add("void test() { /*after full*/");
+        history.add("    System.err.println(1);");
+        history.add("}");
+
+        previousSnippetAndAssert(history, "void test() { /*after full*/");
+    }
+
+    public void testSaveOneHistory() {
+        JShell eval = JShell.builder()
+                .in(new ByteArrayInputStream(new byte[0]))
+                .out(new PrintStream(new ByteArrayOutputStream()))
+                .err(new PrintStream(new ByteArrayOutputStream()))
+                .build();
+        SourceCodeAnalysis analysis = eval.sourceCodeAnalysis();
+        MemoryPreferences prefs = new MemoryPreferences(null, "");
+        EditingHistory history = new EditingHistory(prefs) {
+            @Override protected CompletionInfo analyzeCompletion(String input) {
+                return analysis.analyzeCompletion(input);
+            }
+        };
+
+        history.add("first");
+        history.save();
+    }
+
+    private void previousAndAssert(EditingHistory history, String expected) {
+        assertTrue(history.previous());
+        assertEquals(history.current().toString(), expected);
+    }
+
+    private void nextAndAssert(EditingHistory history, String expected) {
+        assertTrue(history.next());
+        assertEquals(history.current().toString(), expected);
+    }
+
+    private void previousSnippetAndAssert(EditingHistory history, String expected) {
+        assertTrue(history.previousSnippet());
+        assertEquals(history.current().toString(), expected);
+    }
+
+    private void nextSnippetAndAssert(EditingHistory history, String expected) {
+        assertTrue(history.nextSnippet());
+        assertEquals(history.current().toString(), expected);
+    }
+
+    private static final class MemoryPreferences extends AbstractPreferences {
+
+        private final Map<String, String> key2Value = new HashMap<>();
+        private final Map<String, MemoryPreferences> key2SubNode = new HashMap<>();
+
+        public MemoryPreferences(AbstractPreferences parent, String name) {
+            super(parent, name);
+        }
+
+        @Override
+        protected void putSpi(String key, String value) {
+            key2Value.put(key, value);
+        }
+
+        @Override
+        protected String getSpi(String key) {
+            return key2Value.get(key);
+        }
+
+        @Override
+        protected void removeSpi(String key) {
+            key2Value.remove(key);
+        }
+
+        @Override
+        protected void removeNodeSpi() throws BackingStoreException {
+            ((MemoryPreferences) parent()).key2SubNode.remove(name());
+        }
+
+        @Override
+        protected String[] keysSpi() throws BackingStoreException {
+            return key2Value.keySet().toArray(new String[key2Value.size()]);
+        }
+
+        @Override
+        protected String[] childrenNamesSpi() throws BackingStoreException {
+            return key2SubNode.keySet().toArray(new String[key2SubNode.size()]);
+        }
+
+        @Override
+        protected AbstractPreferences childSpi(String name) {
+            return key2SubNode.computeIfAbsent(name, n -> new MemoryPreferences(this, n));
+        }
+
+        @Override
+        protected void syncSpi() throws BackingStoreException {}
+
+        @Override
+        protected void flushSpi() throws BackingStoreException {}
+
+    }
+
+}
diff --git a/langtools/test/jdk/jshell/IOTest.java b/langtools/test/jdk/jshell/IOTest.java
new file mode 100644
index 0000000..112b956
--- /dev/null
+++ b/langtools/test/jdk/jshell/IOTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 input/output
+ * @build KullaTesting TestingInputStream
+ * @run testng IOTest
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class IOTest extends KullaTesting {
+
+    String LINE_SEPARATOR = System.getProperty("line.separator");
+
+    public void testOutput() {
+        assertEval("System.out.println(\"Test\");");
+        assertEquals(getOutput(), "Test" + LINE_SEPARATOR);
+    }
+
+    public void testErrorOutput() {
+        assertEval("System.err.println(\"Oops\");");
+        assertEquals(getErrorOutput(), "Oops" + LINE_SEPARATOR);
+    }
+
+    public void testInput() {
+        setInput("x");
+        assertEval("(char)System.in.read();", "'x'");
+    }
+}
diff --git a/langtools/test/jdk/jshell/IdGeneratorTest.java b/langtools/test/jdk/jshell/IdGeneratorTest.java
new file mode 100644
index 0000000..1a3f167
--- /dev/null
+++ b/langtools/test/jdk/jshell/IdGeneratorTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 custom id generators
+ * @build KullaTesting TestingInputStream
+ * @run testng IdGeneratorTest
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+import java.util.function.Supplier;
+
+import jdk.jshell.EvalException;
+import jdk.jshell.JShell;
+import jdk.jshell.PersistentSnippet;
+import jdk.jshell.SnippetEvent;
+import jdk.jshell.UnresolvedReferenceException;
+import jdk.jshell.VarSnippet;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class IdGeneratorTest {
+
+    public JShell.Builder getBuilder() {
+        TestingInputStream inStream = new TestingInputStream();
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        ByteArrayOutputStream errStream = new ByteArrayOutputStream();
+        return JShell.builder()
+                .in(inStream)
+                .out(new PrintStream(outStream))
+                .err(new PrintStream(errStream));
+    }
+
+    public void testTempNameGenerator() {
+        JShell.Builder builder = getBuilder().tempVariableNameGenerator(new Supplier<String>() {
+            int count = 0;
+
+            @Override
+            public String get() {
+                return "temp" + ++count;
+            }
+        });
+        try (JShell jShell = builder.build()) {
+            for (int i = 0; i < 3; ++i) {
+                VarSnippet v = (VarSnippet) jShell.eval("2 + " + (i + 1)).get(0).snippet();
+                assertEquals("temp" + (i + 1), v.name(), "Custom id: ");
+            }
+        }
+    }
+
+    public void testResetTempNameGenerator() {
+        JShell.Builder builder = getBuilder().tempVariableNameGenerator(() -> {
+            throw new AssertionError("Should not be called");
+        });
+        try (JShell jShell = builder.tempVariableNameGenerator(null).build()) {
+            jShell.eval("2 + 2");
+        }
+    }
+
+    public void testIdGenerator() {
+        JShell.Builder builder = getBuilder().idGenerator(((snippet, id) -> "custom" + id));
+        try (JShell jShell = builder.build()) {
+            List<SnippetEvent> eval = jShell.eval("int a, b;");
+            checkIds(eval);
+            checkIds(jShell.drop((PersistentSnippet) eval.get(0).snippet()));
+        }
+    }
+
+    private void checkIds(List<SnippetEvent> events) {
+        for (SnippetEvent event : events) {
+            assertTrue(event.snippet().id().startsWith("custom"), "Not started with \"custom\": "
+                    + event.snippet().id());
+        }
+    }
+
+    @Test(enabled = false) // TODO 8133507
+    public void testIdInException() {
+        JShell.Builder builder = getBuilder().idGenerator(((snippet, id) -> "custom" + id));
+        try (JShell jShell = builder.build()) {
+            EvalException evalException = (EvalException) jShell.eval("throw new Error();").get(0).exception();
+            for (StackTraceElement ste : evalException.getStackTrace()) {
+                assertTrue(ste.getFileName().startsWith("custom"), "Not started with \"custom\": "
+                        + ste.getFileName());
+            }
+            jShell.eval("void f() { g(); }");
+            UnresolvedReferenceException unresolvedException = (UnresolvedReferenceException) jShell.eval("f();").get(0).exception();
+            for (StackTraceElement ste : unresolvedException.getStackTrace()) {
+                assertTrue(ste.getFileName().startsWith("custom"), "Not started with \"custom\": "
+                        + ste.getFileName());
+            }
+        }
+    }
+
+    public void testResetIdGenerator() {
+        JShell.Builder builder = getBuilder().idGenerator((sn, id) -> {
+            throw new AssertionError("Should not be called");
+        });
+        try (JShell jShell = builder.idGenerator(null).build()) {
+            jShell.eval("2 + 2");
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/IgnoreTest.java b/langtools/test/jdk/jshell/IgnoreTest.java
new file mode 100644
index 0000000..08c648a
--- /dev/null
+++ b/langtools/test/jdk/jshell/IgnoreTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 the ignoring of comments and certain modifiers
+ * @build KullaTesting TestingInputStream
+ * @run testng IgnoreTest
+ */
+
+import org.testng.annotations.Test;
+
+import jdk.jshell.MethodSnippet;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.VarSnippet;
+import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Snippet.SubKind.*;
+
+@Test
+public class IgnoreTest extends KullaTesting {
+
+    public void testComment() {
+        assertVarKeyMatch("//t1\n int//t2\n x//t3\n =//t4\n 12//t5\n ;//t6\n",
+                true, "x", VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, "int", added(VALID));
+        assertVarKeyMatch("//t1\n int//t2\n y//t3\n =//t4\n 12//t5\n ;//t6",
+                true, "y", VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, "int", added(VALID));
+        assertDeclarationKeyMatch("       //t0\n" +
+                        "       int//t0\n" +
+                        "       f//t0\n" +
+                        "       (//t0\n" +
+                        "       int x//t1\n" +
+                        "       ) {//t2\n" +
+                        "       return x+//t3\n" +
+                        "       x//t4\n" +
+                        "       ;//t5\n" +
+                        "       }//t6",
+                false, "f", METHOD_SUBKIND, added(VALID));
+    }
+
+    public void testVarModifier() {
+        VarSnippet x1 = (VarSnippet) assertDeclareWarn1("public int x1;", "jdk.eval.warn.illegal.modifiers");
+        assertVariableDeclSnippet(x1, "x1", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
+        VarSnippet x2 = (VarSnippet) assertDeclareWarn1("protected int x2;", "jdk.eval.warn.illegal.modifiers");
+        assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
+        VarSnippet x3 = (VarSnippet) assertDeclareWarn1("private int x3;", "jdk.eval.warn.illegal.modifiers");
+        assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
+        VarSnippet x4 = (VarSnippet) assertDeclareWarn1("static int x4;", "jdk.eval.warn.illegal.modifiers");
+        assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
+        VarSnippet x5 = (VarSnippet) assertDeclareWarn1("final int x5;", "jdk.eval.warn.illegal.modifiers");
+        assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1);
+    }
+
+    public void testMethodModifier() {
+        MethodSnippet m1 = (MethodSnippet) assertDeclareWarn1("public void m1() {}", "jdk.eval.warn.illegal.modifiers");
+        assertMethodDeclSnippet(m1, "m1", "()void", VALID, 0, 1);
+        MethodSnippet m2 = (MethodSnippet) assertDeclareWarn1("protected void m2() {}", "jdk.eval.warn.illegal.modifiers");
+        assertMethodDeclSnippet(m2, "m2", "()void", VALID, 0, 1);
+        MethodSnippet m3 = (MethodSnippet) assertDeclareWarn1("private void m3() {}", "jdk.eval.warn.illegal.modifiers");
+        assertMethodDeclSnippet(m3, "m3", "()void", VALID, 0, 1);
+        MethodSnippet m4 = (MethodSnippet) assertDeclareWarn1("static void m4() {}", "jdk.eval.warn.illegal.modifiers");
+        assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 1);
+        MethodSnippet m5 = (MethodSnippet) assertDeclareWarn1("final void m5() {}", "jdk.eval.warn.illegal.modifiers");
+        assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 1);
+    }
+
+    public void testClassModifier() {
+        TypeDeclSnippet c1 = (TypeDeclSnippet) assertDeclareWarn1("public class C1 {}", "jdk.eval.warn.illegal.modifiers");
+        assertTypeDeclSnippet(c1, "C1", VALID, CLASS_SUBKIND, 0, 1);
+        TypeDeclSnippet c2 = (TypeDeclSnippet) assertDeclareWarn1("protected class C2 {}", "jdk.eval.warn.illegal.modifiers");
+        assertTypeDeclSnippet(c2, "C2", VALID, CLASS_SUBKIND, 0, 1);
+        TypeDeclSnippet c3 = (TypeDeclSnippet) assertDeclareWarn1("private class C3 {}", "jdk.eval.warn.illegal.modifiers");
+        assertTypeDeclSnippet(c3, "C3", VALID, CLASS_SUBKIND, 0, 1);
+        TypeDeclSnippet c4 = (TypeDeclSnippet) assertDeclareWarn1("static class C4 {}", "jdk.eval.warn.illegal.modifiers");
+        assertTypeDeclSnippet(c4, "C4", VALID, CLASS_SUBKIND, 0, 1);
+        TypeDeclSnippet c5 = (TypeDeclSnippet) assertDeclareWarn1("final class C5 {}", "jdk.eval.warn.illegal.modifiers");
+        assertTypeDeclSnippet(c5, "C5", VALID, CLASS_SUBKIND, 0, 1);
+    }
+
+    public void testInsideModifier() {
+        assertEval("import static java.lang.reflect.Modifier.*;");
+        assertEval("class C {"
+                + "public int z;"
+                + "final int f = 3;"
+                + "protected int a;"
+                + "private void m() {}"
+                + "static void b() {}"
+                + "}");
+        assertEval("C.class.getDeclaredField(\"z\").getModifiers() == PUBLIC;", "true");
+        assertEval("C.class.getDeclaredField(\"f\").getModifiers() == FINAL;", "true");
+        assertEval("C.class.getDeclaredField(\"a\").getModifiers() == PROTECTED;", "true");
+        assertEval("C.class.getDeclaredMethod(\"m\").getModifiers() == PRIVATE;", "true");
+        assertEval("C.class.getDeclaredMethod(\"b\").getModifiers() == STATIC;", "true");
+    }
+}
diff --git a/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java b/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java
new file mode 100644
index 0000000..86fd431
--- /dev/null
+++ b/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Testing IllegalArgumentException.
+ * @build KullaTesting TestingInputStream IllegalArgumentExceptionTest
+ * @run testng IllegalArgumentExceptionTest
+ */
+
+import java.util.function.Consumer;
+
+import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.PersistentSnippet;
+import jdk.jshell.Snippet;
+import jdk.jshell.VarSnippet;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+import static jdk.jshell.Snippet.Status.VALID;
+
+@Test
+public class IllegalArgumentExceptionTest extends KullaTesting {
+
+    private void testIllegalArgumentException(Consumer<Snippet> action) {
+        Snippet key = varKey(assertEval("int value;", added(VALID)));
+        tearDown();
+        setUp();
+        assertEval("double value;");
+        try {
+            action.accept(key);
+            fail("Exception expected.");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    public void testVarValue() {
+        testIllegalArgumentException((key) -> getState().varValue((VarSnippet) key));
+    }
+
+    public void testStatus() {
+        testIllegalArgumentException((key) -> getState().status(key));
+    }
+
+    public void testDrop() {
+        testIllegalArgumentException((key) -> getState().drop((PersistentSnippet) key));
+    }
+
+    public void testUnresolved() {
+        testIllegalArgumentException((key) -> getState().unresolvedDependencies((DeclarationSnippet) key));
+    }
+
+    public void testDiagnostics() {
+        testIllegalArgumentException((key) -> getState().diagnostics(key));
+    }
+}
diff --git a/langtools/test/jdk/jshell/ImportTest.java b/langtools/test/jdk/jshell/ImportTest.java
new file mode 100644
index 0000000..2cf555e
--- /dev/null
+++ b/langtools/test/jdk/jshell/ImportTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 imports
+ * @library /tools/lib
+ * @build KullaTesting TestingInputStream ToolBox ExpectedDiagnostic
+ * @run testng ImportTest
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Snippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+import static jdk.jshell.Snippet.SubKind.SINGLE_TYPE_IMPORT_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.SINGLE_STATIC_IMPORT_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.TYPE_IMPORT_ON_DEMAND_SUBKIND;
+import static jdk.jshell.Snippet.SubKind.STATIC_IMPORT_ON_DEMAND_SUBKIND;
+
+@Test
+public class ImportTest extends KullaTesting {
+
+    public void testImport() {
+        assertImportKeyMatch("import java.util.List;", "List", SINGLE_TYPE_IMPORT_SUBKIND, added(VALID));
+        assertImportKeyMatch("import java.util.ArrayList;", "ArrayList", SINGLE_TYPE_IMPORT_SUBKIND, added(VALID));
+        assertEval("List<Integer> list = new ArrayList<>();");
+        assertEval("list.add(45);");
+        assertEval("list.size();", "1");
+    }
+
+    public void testImportOnDemand() {
+        assertImportKeyMatch("import java.util.*;", "java.util.*", TYPE_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
+        assertEval("List<Integer> list = new ArrayList<>();");
+        assertEval("list.add(45);");
+        assertEval("list.size();", "1");
+    }
+
+    public void testImportStatic() {
+        assertImportKeyMatch("import static java.lang.Math.PI;", "PI", SINGLE_STATIC_IMPORT_SUBKIND, added(VALID));
+        assertEval("new Double(PI).toString().substring(0, 16).equals(\"3.14159265358979\");", "true");
+    }
+
+    public void testImportStaticOnDemand() {
+        assertImportKeyMatch("import static java.lang.Math.*;", "java.lang.Math.*", STATIC_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
+        assertEval("abs(cos(PI / 2)) < 0.00001;", "true");
+    }
+
+    @Test(enabled = false) // TODO 8129418
+    public void testUnknownPackage() {
+        assertDeclareFail("import unknown.qqq;",
+                new ExpectedDiagnostic("compiler.err.doesnt.exist", 7, 18, 14, -1, -1, Diagnostic.Kind.ERROR));
+        assertDeclareFail("import unknown.*;",
+                new ExpectedDiagnostic("compiler.err.doesnt.exist", 7, 15, 7, -1, -1, Diagnostic.Kind.ERROR));
+    }
+
+    public void testBogusImportIgnoredInFuture() {
+        assertDeclareFail("import unknown.qqq;", "compiler.err.doesnt.exist");
+        assertDeclareFail("import unknown.*;", "compiler.err.doesnt.exist");
+        assertEval("2 + 2;");
+    }
+
+    public void testBadImport() {
+        assertDeclareFail("import static java.lang.reflect.Modifier;",
+                new ExpectedDiagnostic("compiler.err.cant.resolve.location", 14, 31, 23, -1, -1, Diagnostic.Kind.ERROR));
+    }
+
+    public void testBadSyntaxImport() {
+        assertDeclareFail("import not found.*;",
+                new ExpectedDiagnostic("compiler.err.expected", 10, 10, 10, -1, -1, Diagnostic.Kind.ERROR));
+    }
+
+    public void testImportRedefinition() {
+        Compiler compiler = new Compiler();
+        Path path = Paths.get("testImport");
+        compiler.compile(path, "package util; public class ArrayList { public String toString() { return \"MyList\"; } }");
+        compiler.compile(path, "package util; public class A { public static class ArrayList {\n" +
+                "public String toString() { return \"MyInnerList\"; } } }");
+        addToClasspath(compiler.getPath(path));
+
+        assertImportKeyMatch("import util.*;", "util.*", TYPE_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
+        assertEval("new ArrayList();", "MyList", added(VALID));
+
+        Snippet import0 = assertImportKeyMatch("import java.util.ArrayList;", "ArrayList", SINGLE_TYPE_IMPORT_SUBKIND, added(VALID));
+        assertEval("new ArrayList();", "[]");
+
+        Snippet import1 = assertImportKeyMatch("import util.ArrayList;", "ArrayList", SINGLE_TYPE_IMPORT_SUBKIND,
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(import0, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("new ArrayList();", "MyList");
+
+        Snippet import2 = assertImportKeyMatch("import java.util.ArrayList;", "ArrayList", SINGLE_TYPE_IMPORT_SUBKIND,
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(import1, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("new ArrayList();", "[]");
+
+        Snippet import3 = assertImportKeyMatch("import util.A.ArrayList;", "ArrayList", SINGLE_TYPE_IMPORT_SUBKIND,
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(import2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("new ArrayList();", "MyInnerList");
+
+        Snippet import4 = assertImportKeyMatch("import java.util.ArrayList;", "ArrayList", SINGLE_TYPE_IMPORT_SUBKIND,
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(import3, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("new ArrayList();", "[]");
+
+        Snippet import5 = assertImportKeyMatch("import static util.A.ArrayList;", "ArrayList", SINGLE_STATIC_IMPORT_SUBKIND,
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(import4, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("new ArrayList();", "MyInnerList");
+    }
+
+    public void testImportMemberRedefinition() {
+        Compiler compiler = new Compiler();
+        Path path = Paths.get("testImport");
+        compiler.compile(path, "package util; public class A {" +
+                "public static String field = \"A\";" +
+                "public static String method() { return \"A\"; } }");
+        compiler.compile(path, "package util; public class B {" +
+                "public static String field = \"B\";" +
+                "public static String method() { return \"B\"; } }");
+        addToClasspath(compiler.getPath(path));
+
+        assertImportKeyMatch("import static util.B.*;", "util.B.*", STATIC_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
+        assertEval("field;", "\"B\"");
+        assertEval("method();", "\"B\"");
+
+        assertImportKeyMatch("import static util.A.method;", "method", SINGLE_STATIC_IMPORT_SUBKIND, added(VALID));
+        assertEval("field;", "\"B\"");
+        assertEval("method();", "\"A\"");
+
+        assertImportKeyMatch("import static util.A.field;", "field", SINGLE_STATIC_IMPORT_SUBKIND, added(VALID));
+        assertEval("field;", "\"A\"");
+        assertEval("method();", "\"A\"");
+    }
+}
diff --git a/langtools/test/jdk/jshell/JShellStateClosedTest.java b/langtools/test/jdk/jshell/JShellStateClosedTest.java
new file mode 100644
index 0000000..e1ce757
--- /dev/null
+++ b/langtools/test/jdk/jshell/JShellStateClosedTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Testing IllegalStateException.
+ * @build KullaTesting TestingInputStream JShellStateClosedTest
+ * @run testng JShellStateClosedTest
+ */
+
+import java.util.function.Consumer;
+
+import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.PersistentSnippet;
+import jdk.jshell.Snippet;
+import jdk.jshell.VarSnippet;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+@Test
+public class JShellStateClosedTest extends KullaTesting {
+
+    private void testStateClosedException(Runnable action) {
+        getState().close();
+        try {
+            action.run();
+            fail("Exception expected");
+        } catch (IllegalStateException e) {
+            // Expected
+        }
+    }
+
+    public void testClasses() {
+        testStateClosedException(() -> getState().types());
+    }
+
+    public void testVariables() {
+        testStateClosedException(() -> getState().variables());
+    }
+
+    public void testMethods() {
+        testStateClosedException(() -> getState().methods());
+    }
+
+    public void testKeys() {
+        testStateClosedException(() -> getState().snippets());
+    }
+
+    public void testEval() {
+        testStateClosedException(() -> getState().eval("int a;"));
+    }
+
+    private void testStateClosedException(Consumer<Snippet> action) {
+        Snippet k = varKey(assertEval("int a;"));
+        getState().close();
+        try {
+            action.accept(k);
+            fail("IllegalStateException expected since closed");
+        } catch (IllegalStateException e) {
+            // Expected
+        }
+    }
+
+    private void testStateClosedWithoutException(Consumer<Snippet> action) {
+        Snippet k = varKey(assertEval("int a;"));
+        getState().close();
+        try {
+            action.accept(k);
+        } catch (IllegalStateException e) {
+            fail("Expected no IllegalStateException even though closed");
+        }
+    }
+
+    public void testStatus() {
+        testStateClosedWithoutException((key) -> getState().status(key));
+    }
+
+    public void testVarValue() {
+        testStateClosedException((key) -> getState().varValue((VarSnippet) key));
+    }
+
+    public void testDrop() {
+        testStateClosedException((key) -> getState().drop((PersistentSnippet) key));
+    }
+
+    public void testUnresolved() {
+        testStateClosedWithoutException((key) -> getState().unresolvedDependencies((DeclarationSnippet) key));
+    }
+
+    public void testDiagnostics() {
+        testStateClosedWithoutException((key) -> getState().diagnostics(key));
+    }
+}
diff --git a/langtools/test/jdk/jshell/KullaCompletenessStressTest.java b/langtools/test/jdk/jshell/KullaCompletenessStressTest.java
new file mode 100644
index 0000000..bfba49a
--- /dev/null
+++ b/langtools/test/jdk/jshell/KullaCompletenessStressTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 SourceCodeAnalysis
+ * @build KullaTesting TestingInputStream KullaCompletenessStressTest CompletenessStressTest
+ * @run testng KullaCompletenessStressTest
+ */
+
+import java.io.File;
+
+import org.testng.annotations.Test;
+
+@Test
+public class KullaCompletenessStressTest extends CompletenessStressTest {
+    @Override
+    public File[] getDirectoriesToTest() {
+        return new File[]{ getKullaSourceDirectory() };
+    }
+
+    public File getKullaSourceDirectory() {
+        String src = System.getProperty("test.src");
+        File file;
+        if (src == null) {
+            file = new File("../src/jdk.jshell/share/classes");
+        } else {
+            file = new File(src, "../../../src/jdk.jshell/share/classes");
+        }
+        return file;
+    }
+}
diff --git a/langtools/test/jdk/jshell/KullaTesting.java b/langtools/test/jdk/jshell/KullaTesting.java
new file mode 100644
index 0000000..c74ee86
--- /dev/null
+++ b/langtools/test/jdk/jshell/KullaTesting.java
@@ -0,0 +1,1144 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.EvalException;
+import jdk.jshell.JShell;
+import jdk.jshell.JShell.Subscription;
+import jdk.jshell.Snippet;
+import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.ExpressionSnippet;
+import jdk.jshell.ImportSnippet;
+import jdk.jshell.Snippet.Kind;
+import jdk.jshell.MethodSnippet;
+import jdk.jshell.PersistentSnippet;
+import jdk.jshell.Snippet.Status;
+import jdk.jshell.Snippet.SubKind;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.VarSnippet;
+import jdk.jshell.SnippetEvent;
+import jdk.jshell.SourceCodeAnalysis;
+import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
+import jdk.jshell.SourceCodeAnalysis.Completeness;
+import jdk.jshell.SourceCodeAnalysis.Suggestion;
+import jdk.jshell.UnresolvedReferenceException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import jdk.jshell.Diag;
+import static jdk.jshell.Snippet.Status.*;
+import static org.testng.Assert.*;
+import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND;
+
+public class KullaTesting {
+
+    public static final String IGNORE_VALUE = "<ignore-value>";
+    public static final Class<? extends Throwable> IGNORE_EXCEPTION = (new Throwable() {}).getClass();
+    public static final Snippet MAIN_SNIPPET;
+
+    private SourceCodeAnalysis analysis = null;
+    private JShell state = null;
+    private TestingInputStream inStream = null;
+    private ByteArrayOutputStream outStream = null;
+    private ByteArrayOutputStream errStream = null;
+
+    private Map<String, Snippet> idToSnippet = new LinkedHashMap<>();
+    private Set<Snippet> allSnippets = new LinkedHashSet<>();
+    private List<String> classpath;
+
+    static {
+        JShell js = JShell.create();
+        MAIN_SNIPPET = js.eval("MAIN_SNIPPET").get(0).snippet();
+        js.close();
+        assertTrue(MAIN_SNIPPET != null, "Bad MAIN_SNIPPET set-up -- must not be null");
+    }
+
+    public enum DiagCheck {
+        DIAG_OK,
+        DIAG_WARNING,
+        DIAG_ERROR,
+        DIAG_IGNORE
+    }
+
+    public void setInput(String s) {
+        inStream.setInput(s);
+    }
+
+    public String getOutput() {
+        String s = outStream.toString();
+        outStream.reset();
+        return s;
+    }
+
+    public String getErrorOutput() {
+        String s = errStream.toString();
+        errStream.reset();
+        return s;
+    }
+
+    /**
+     * @return the analysis
+     */
+    public SourceCodeAnalysis getAnalysis() {
+        if (analysis == null) {
+            analysis = state.sourceCodeAnalysis();
+        }
+        return analysis;
+    }
+
+    /**
+     * @return the state
+     */
+    public JShell getState() {
+        return state;
+    }
+
+    public List<Snippet> getActiveKeys() {
+        return allSnippets.stream()
+                .filter(k -> getState().status(k).isActive)
+                .collect(Collectors.toList());
+    }
+
+    public void addToClasspath(String path) {
+        classpath.add(path);
+        getState().addToClasspath(path);
+    }
+
+    public void addToClasspath(Path path) {
+        addToClasspath(path.toString());
+    }
+
+    @BeforeMethod
+    public void setUp() {
+        inStream = new TestingInputStream();
+        outStream = new ByteArrayOutputStream();
+        errStream = new ByteArrayOutputStream();
+        state = JShell.builder()
+                .in(inStream)
+                .out(new PrintStream(outStream))
+                .err(new PrintStream(errStream))
+                .build();
+        allSnippets = new LinkedHashSet<>();
+        idToSnippet = new LinkedHashMap<>();
+        classpath = new ArrayList<>();
+    }
+
+    @AfterMethod
+    public void tearDown() {
+        if (state != null) state.close();
+        state = null;
+        analysis = null;
+        allSnippets = null;
+        idToSnippet = null;
+        classpath = null;
+    }
+
+    public List<String> assertUnresolvedDependencies(DeclarationSnippet key, int unresolvedSize) {
+        List<String> unresolved = getState().unresolvedDependencies(key);
+        assertEquals(unresolved.size(), unresolvedSize, "Input: " + key.source() + ", checking unresolved: ");
+        return unresolved;
+    }
+
+    public DeclarationSnippet assertUnresolvedDependencies1(DeclarationSnippet key, Status status, String name) {
+        List<String> unresolved = assertUnresolvedDependencies(key, 1);
+        String input = key.source();
+        assertEquals(unresolved.size(), 1, "Given input: " + input + ", checking unresolved");
+        assertEquals(unresolved.get(0), name, "Given input: " + input + ", checking unresolved: ");
+        assertEquals(getState().status(key), status, "Given input: " + input + ", checking status: ");
+        return key;
+    }
+
+    public MethodSnippet assertEvalUnresolvedException(String input, String name, int unresolvedSize, int diagnosticsSize) {
+        List<SnippetEvent> events = assertEval(input, null, UnresolvedReferenceException.class, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, null);
+        SnippetEvent ste = events.get(0);
+        MethodSnippet methodKey = ((UnresolvedReferenceException) ste.exception()).getMethodSnippet();
+        assertEquals(methodKey.name(), name, "Given input: " + input + ", checking name");
+        assertEquals(getState().unresolvedDependencies(methodKey).size(), unresolvedSize, "Given input: " + input + ", checking unresolved");
+        assertEquals(getState().diagnostics(methodKey).size(), diagnosticsSize, "Given input: " + input + ", checking diagnostics");
+        return methodKey;
+    }
+
+    public Snippet assertKeyMatch(String input, boolean isExecutable, SubKind expectedSubKind, STEInfo mainInfo, STEInfo... updates) {
+        Snippet key = key(assertEval(input, IGNORE_VALUE, mainInfo, updates));
+        String source = key.source();
+        assertEquals(source, input, "Key \"" + input + "\" source mismatch, got: " + source + ", expected: " + input);
+        SubKind subkind = key.subKind();
+        assertEquals(subkind, expectedSubKind, "Key \"" + input + "\" subkind mismatch, got: "
+                + subkind + ", expected: " + expectedSubKind);
+        assertEquals(subkind.isExecutable(), isExecutable, "Key \"" + input + "\", expected isExecutable: "
+                + isExecutable + ", got: " + subkind.isExecutable());
+        Snippet.Kind expectedKind = getKind(key);
+        assertEquals(key.kind(), expectedKind, "Checking kind: ");
+        assertEquals(expectedSubKind.kind(), expectedKind, "Checking kind: ");
+        return key;
+    }
+
+    private Kind getKind(Snippet key) {
+        SubKind expectedSubKind = key.subKind();
+        Kind expectedKind;
+        switch (expectedSubKind) {
+            case SINGLE_TYPE_IMPORT_SUBKIND:
+            case SINGLE_STATIC_IMPORT_SUBKIND:
+            case TYPE_IMPORT_ON_DEMAND_SUBKIND:
+            case STATIC_IMPORT_ON_DEMAND_SUBKIND:
+                expectedKind = Kind.IMPORT;
+                break;
+            case CLASS_SUBKIND:
+            case INTERFACE_SUBKIND:
+            case ENUM_SUBKIND:
+            case ANNOTATION_TYPE_SUBKIND:
+                expectedKind = Kind.TYPE_DECL;
+                break;
+            case METHOD_SUBKIND:
+                expectedKind = Kind.METHOD;
+                break;
+            case VAR_DECLARATION_SUBKIND:
+            case TEMP_VAR_EXPRESSION_SUBKIND:
+            case VAR_DECLARATION_WITH_INITIALIZER_SUBKIND:
+                expectedKind = Kind.VAR;
+                break;
+            case VAR_VALUE_SUBKIND:
+            case ASSIGNMENT_SUBKIND:
+                expectedKind = Kind.EXPRESSION;
+                break;
+            case STATEMENT_SUBKIND:
+                expectedKind = Kind.STATEMENT;
+                break;
+            case UNKNOWN_SUBKIND:
+                expectedKind = Kind.ERRONEOUS;
+                break;
+            default:
+                throw new AssertionError("Unsupported key: " + key.getClass().getCanonicalName());
+        }
+        return expectedKind;
+    }
+
+    public ImportSnippet assertImportKeyMatch(String input, String name, SubKind subkind, STEInfo mainInfo, STEInfo... updates) {
+        Snippet key = assertKeyMatch(input, false, subkind, mainInfo, updates);
+
+        assertTrue(key instanceof ImportSnippet, "Expected an ImportKey, got: " + key.getClass().getName());
+        ImportSnippet importKey = (ImportSnippet) key;
+        assertEquals(importKey.name(), name, "Input \"" + input +
+                "\" name mismatch, got: " + importKey.name() + ", expected: " + name);
+        assertEquals(importKey.kind(), Kind.IMPORT, "Checking kind: ");
+        return importKey;
+    }
+
+    public DeclarationSnippet assertDeclarationKeyMatch(String input, boolean isExecutable, String name, SubKind subkind, STEInfo mainInfo, STEInfo... updates) {
+        Snippet key = assertKeyMatch(input, isExecutable, subkind, mainInfo, updates);
+
+        assertTrue(key instanceof DeclarationSnippet, "Expected a DeclarationKey, got: " + key.getClass().getName());
+        DeclarationSnippet declKey = (DeclarationSnippet) key;
+        assertEquals(declKey.name(), name, "Input \"" + input +
+                "\" name mismatch, got: " + declKey.name() + ", expected: " + name);
+        return declKey;
+    }
+
+    public VarSnippet assertVarKeyMatch(String input, boolean isExecutable, String name, SubKind kind, String typeName, STEInfo mainInfo, STEInfo... updates) {
+        Snippet sn = assertDeclarationKeyMatch(input, isExecutable, name, kind, mainInfo, updates);
+        assertTrue(sn instanceof VarSnippet, "Expected a VarKey, got: " + sn.getClass().getName());
+        VarSnippet variableKey = (VarSnippet) sn;
+        String signature = variableKey.typeName();
+        assertEquals(signature, typeName, "Key \"" + input +
+                "\" typeName mismatch, got: " + signature + ", expected: " + typeName);
+        assertEquals(variableKey.kind(), Kind.VAR, "Checking kind: ");
+        return variableKey;
+    }
+
+    public void assertExpressionKeyMatch(String input, String name, SubKind kind, String typeName) {
+        Snippet key = assertKeyMatch(input, true, kind, added(VALID));
+        assertTrue(key instanceof ExpressionSnippet, "Expected a ExpressionKey, got: " + key.getClass().getName());
+        ExpressionSnippet exprKey = (ExpressionSnippet) key;
+        assertEquals(exprKey.name(), name, "Input \"" + input +
+                "\" name mismatch, got: " + exprKey.name() + ", expected: " + name);
+        assertEquals(exprKey.typeName(), typeName, "Key \"" + input +
+                "\" typeName mismatch, got: " + exprKey.typeName() + ", expected: " + typeName);
+        assertEquals(exprKey.kind(), Kind.EXPRESSION, "Checking kind: ");
+    }
+
+    // For expressions throwing an EvalException
+    public SnippetEvent assertEvalException(String input) {
+        List<SnippetEvent> events = assertEval(input, null, EvalException.class,
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, null);
+        return events.get(0);
+    }
+
+
+    public List<SnippetEvent> assertEvalFail(String input) {
+        return assertEval(input, null, null,
+                DiagCheck.DIAG_ERROR, DiagCheck.DIAG_IGNORE, added(REJECTED));
+    }
+
+    public List<SnippetEvent> assertEval(String input) {
+        return assertEval(input, IGNORE_VALUE, null, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, added(VALID));
+    }
+
+    public List<SnippetEvent> assertEval(String input, String value) {
+        return assertEval(input, value, null, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, added(VALID));
+    }
+
+    public List<SnippetEvent> assertEval(String input, STEInfo mainInfo, STEInfo... updates) {
+        return assertEval(input, IGNORE_VALUE, null, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, mainInfo, updates);
+    }
+
+    public List<SnippetEvent> assertEval(String input, String value,
+            STEInfo mainInfo, STEInfo... updates) {
+        return assertEval(input, value, null, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, mainInfo, updates);
+    }
+
+    public List<SnippetEvent> assertEval(String input, DiagCheck diagMain, DiagCheck diagUpdates) {
+        return assertEval(input, IGNORE_VALUE, null, diagMain, diagUpdates, added(VALID));
+    }
+
+    public List<SnippetEvent> assertEval(String input, DiagCheck diagMain, DiagCheck diagUpdates,
+            STEInfo mainInfo, STEInfo... updates) {
+        return assertEval(input, IGNORE_VALUE, null, diagMain, diagUpdates, mainInfo, updates);
+    }
+
+    public List<SnippetEvent> assertEval(String input,
+            String value, Class<? extends Throwable> exceptionClass,
+            DiagCheck diagMain, DiagCheck diagUpdates,
+            STEInfo mainInfo, STEInfo... updates) {
+        return assertEval(input, diagMain, diagUpdates, new EventChain(mainInfo, value, exceptionClass, updates));
+    }
+
+    // Use this directly or usually indirectly for all non-empty calls to eval()
+    public List<SnippetEvent> assertEval(String input,
+           DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
+        return checkEvents(() -> getState().eval(input), "eval(" + input + ")", diagMain, diagUpdates, eventChains);
+    }
+
+    private Map<Snippet, Snippet> closure(List<SnippetEvent> events) {
+        Map<Snippet, Snippet> transitions = new HashMap<>();
+        for (SnippetEvent event : events) {
+            transitions.put(event.snippet(), event.causeSnippet());
+        }
+        Map<Snippet, Snippet> causeSnippets = new HashMap<>();
+        for (Map.Entry<Snippet, Snippet> entry : transitions.entrySet()) {
+            Snippet snippet = entry.getKey();
+            Snippet cause = getInitialCause(transitions, entry.getValue());
+            causeSnippets.put(snippet, cause);
+        }
+        return causeSnippets;
+    }
+
+    private Snippet getInitialCause(Map<Snippet, Snippet> transitions, Snippet snippet) {
+        Snippet result;
+        while ((result = transitions.get(snippet)) != null) {
+            snippet = result;
+        }
+        return snippet;
+    }
+
+    private Map<Snippet, List<SnippetEvent>> groupByCauseSnippet(List<SnippetEvent> events) {
+        Map<Snippet, List<SnippetEvent>> map = new TreeMap<>((a, b) -> a.id().compareTo(b.id()));
+        for (SnippetEvent event : events) {
+            if (event == null) {
+                throw new InternalError("null event found in " + events);
+            }
+            if (event.snippet() == null) {
+                throw new InternalError("null event Snippet found in " + events);
+            }
+            if (event.snippet().id() == null) {
+                throw new InternalError("null event Snippet id() found in " + events);
+            }
+        }
+        for (SnippetEvent event : events) {
+            if (event.causeSnippet() == null) {
+                map.computeIfAbsent(event.snippet(), ($) -> new ArrayList<>()).add(event);
+            }
+        }
+        Map<Snippet, Snippet> causeSnippets = closure(events);
+        for (SnippetEvent event : events) {
+            Snippet causeSnippet = causeSnippets.get(event.snippet());
+            if (causeSnippet != null) {
+                map.get(causeSnippet).add(event);
+            }
+        }
+        for (Map.Entry<Snippet, List<SnippetEvent>> entry : map.entrySet()) {
+            Collections.sort(entry.getValue(),
+                    (a, b) -> a.causeSnippet() == null
+                            ? -1 : b.causeSnippet() == null
+                            ? 1 : a.snippet().id().compareTo(b.snippet().id()));
+        }
+        return map;
+    }
+
+    private List<STEInfo> getInfos(EventChain... eventChains) {
+        List<STEInfo> list = new ArrayList<>();
+        for (EventChain i : eventChains) {
+            list.add(i.mainInfo);
+            Collections.addAll(list, i.updates);
+        }
+        return list;
+    }
+
+    private List<SnippetEvent> checkEvents(Supplier<List<SnippetEvent>> toTest,
+             String descriptor,
+             DiagCheck diagMain, DiagCheck diagUpdates,
+             EventChain... eventChains) {
+        List<SnippetEvent> dispatched = new ArrayList<>();
+        Subscription token = getState().onSnippetEvent(kse -> {
+            if (dispatched.size() > 0 && dispatched.get(dispatched.size() - 1) == null) {
+                throw new RuntimeException("dispatch event after done");
+            }
+            dispatched.add(kse);
+        });
+        List<SnippetEvent> events = toTest.get();
+        getState().unsubscribe(token);
+        assertEquals(dispatched.size(), events.size(), "dispatched event size not the same as event size");
+        for (int i = events.size() - 1; i >= 0; --i) {
+            assertEquals(dispatched.get(i), events.get(i), "Event element " + i + " does not match");
+        }
+        dispatched.add(null); // mark end of dispatchs
+
+        for (SnippetEvent evt : events) {
+            assertTrue(evt.snippet() != null, "key must never be null, but it was for: " + descriptor);
+            assertTrue(evt.previousStatus() != null, "previousStatus must never be null, but it was for: " + descriptor);
+            assertTrue(evt.status() != null, "status must never be null, but it was for: " + descriptor);
+            assertTrue(evt.status() != NONEXISTENT, "status must not be NONEXISTENT: " + descriptor);
+            if (evt.previousStatus() != NONEXISTENT) {
+                Snippet old = idToSnippet.get(evt.snippet().id());
+                if (old != null) {
+                    switch (evt.status()) {
+                        case DROPPED:
+                            assertEquals(old, evt.snippet(),
+                                    "Drop: Old snippet must be what is dropped -- input: " + descriptor);
+                            break;
+                        case OVERWRITTEN:
+                            assertEquals(old, evt.snippet(),
+                                    "Overwrite: Old snippet (" + old
+                                    + ") must be what is overwritten -- input: "
+                                    + descriptor + " -- " + evt);
+                            break;
+                        default:
+                            if (evt.causeSnippet() == null) {
+                                // New source
+                                assertNotEquals(old, evt.snippet(),
+                                        "New source: Old snippet must be different from the replacing -- input: "
+                                        + descriptor);
+                            } else {
+                                // An update (key Overwrite??)
+                                assertEquals(old, evt.snippet(),
+                                        "Update: Old snippet must be equal to the replacing -- input: "
+                                        + descriptor);
+                            }
+                            break;
+                    }
+                }
+            }
+        }
+        for (SnippetEvent evt : events) {
+            if (evt.causeSnippet() == null && evt.status() != DROPPED) {
+                allSnippets.add(evt.snippet());
+                idToSnippet.put(evt.snippet().id(), evt.snippet());
+            }
+        }
+        assertTrue(events.size() >= 1, "Expected at least one event, got none.");
+        List<STEInfo> all = getInfos(eventChains);
+        if (events.size() != all.size()) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Got events --\n");
+            for (SnippetEvent evt : events) {
+                sb.append("  key: ").append(evt.snippet());
+                sb.append(" before: ").append(evt.previousStatus());
+                sb.append(" status: ").append(evt.status());
+                sb.append(" isSignatureChange: ").append(evt.isSignatureChange());
+                sb.append(" cause: ");
+                if (evt.causeSnippet() == null) {
+                    sb.append("direct");
+                } else {
+                    sb.append(evt.causeSnippet());
+                }
+                sb.append("\n");
+            }
+            sb.append("Expected ").append(all.size());
+            sb.append(" events, got: ").append(events.size());
+            fail(sb.toString());
+        }
+
+        int impactId = 0;
+        Map<Snippet, List<SnippetEvent>> groupedEvents = groupByCauseSnippet(events);
+        assertEquals(groupedEvents.size(), eventChains.length, "Number of main events");
+        for (Map.Entry<Snippet, List<SnippetEvent>> entry : groupedEvents.entrySet()) {
+            EventChain eventChain = eventChains[impactId++];
+            SnippetEvent main = entry.getValue().get(0);
+            Snippet mainKey = main.snippet();
+            if (eventChain.mainInfo != null) {
+                eventChain.mainInfo.assertMatch(entry.getValue().get(0), mainKey);
+                if (eventChain.updates.length > 0) {
+                    if (eventChain.updates.length == 1) {
+                        eventChain.updates[0].assertMatch(entry.getValue().get(1), mainKey);
+                    } else {
+                        Arrays.sort(eventChain.updates, (a, b) -> ((a.snippet() == MAIN_SNIPPET)
+                                ? mainKey
+                                : a.snippet()).id().compareTo(b.snippet().id()));
+                        List<SnippetEvent> updateEvents = new ArrayList<>(entry.getValue().subList(1, entry.getValue().size()));
+                        int idx = 0;
+                        for (SnippetEvent ste : updateEvents) {
+                            eventChain.updates[idx++].assertMatch(ste, mainKey);
+                        }
+                    }
+                }
+            }
+            if (((Object) eventChain.value) != IGNORE_VALUE) {
+                assertEquals(main.value(), eventChain.value, "Expected execution value of: " + eventChain.value +
+                        ", but got: " + main.value());
+            }
+            if (eventChain.exceptionClass != IGNORE_EXCEPTION) {
+                if (main.exception() == null) {
+                    assertEquals(eventChain.exceptionClass, null, "Expected an exception of class "
+                            + eventChain.exceptionClass + " got no exception");
+                } else if (eventChain.exceptionClass == null) {
+                    fail("Expected no exception but got " + main.exception().toString());
+                } else {
+                    assertTrue(eventChain.exceptionClass.isInstance(main.exception()),
+                            "Expected an exception of class " + eventChain.exceptionClass +
+                                    " got: " + main.exception().toString());
+                }
+            }
+            List<Diag> diagnostics = getState().diagnostics(mainKey);
+            switch (diagMain) {
+                case DIAG_OK:
+                    assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics));
+                    break;
+                case DIAG_WARNING:
+                    assertFalse(hasFatalError(diagnostics), "Expected no errors, got: " + diagnosticsToString(diagnostics));
+                    break;
+                case DIAG_ERROR:
+                    assertTrue(hasFatalError(diagnostics), "Expected errors, got: " + diagnosticsToString(diagnostics));
+                    break;
+            }
+            if (eventChain.mainInfo != null) {
+                for (STEInfo ste : eventChain.updates) {
+                    diagnostics = getState().diagnostics(ste.snippet());
+                    switch (diagUpdates) {
+                        case DIAG_OK:
+                            assertEquals(diagnostics.size(), 0, "Expected no diagnostics, got: " + diagnosticsToString(diagnostics));
+                            break;
+                        case DIAG_WARNING:
+                            assertFalse(hasFatalError(diagnostics), "Expected no errors, got: " + diagnosticsToString(diagnostics));
+                            break;
+                    }
+                }
+            }
+        }
+        return events;
+    }
+
+    // Use this for all EMPTY calls to eval()
+    public void assertEvalEmpty(String input) {
+        List<SnippetEvent> events = getState().eval(input);
+        assertEquals(events.size(), 0, "Expected no events, got: " + events.size());
+    }
+
+    public VarSnippet varKey(List<SnippetEvent> events) {
+        Snippet key = key(events);
+        assertTrue(key instanceof VarSnippet, "Expected a VariableKey, got: " + key);
+        return (VarSnippet) key;
+    }
+
+    public MethodSnippet methodKey(List<SnippetEvent> events) {
+        Snippet key = key(events);
+        assertTrue(key instanceof MethodSnippet, "Expected a MethodKey, got: " + key);
+        return (MethodSnippet) key;
+    }
+
+    public TypeDeclSnippet classKey(List<SnippetEvent> events) {
+        Snippet key = key(events);
+        assertTrue(key instanceof TypeDeclSnippet, "Expected a ClassKey, got: " + key);
+        return (TypeDeclSnippet) key;
+    }
+
+    public ImportSnippet importKey(List<SnippetEvent> events) {
+        Snippet key = key(events);
+        assertTrue(key instanceof ImportSnippet, "Expected a ImportKey, got: " + key);
+        return (ImportSnippet) key;
+    }
+
+    private Snippet key(List<SnippetEvent> events) {
+        assertTrue(events.size() >= 1, "Expected at least one event, got none.");
+        return events.get(0).snippet();
+    }
+
+    public void assertVarValue(Snippet key, String expected) {
+        String value = state.varValue((VarSnippet) key);
+        assertEquals(value, expected, "Expected var value of: " + expected + ", but got: " + value);
+    }
+
+    public Snippet assertDeclareFail(String input, String expectedErrorCode) {
+        return assertDeclareFail(input, expectedErrorCode, added(REJECTED));
+    }
+
+    public Snippet assertDeclareFail(String input, String expectedErrorCode,
+            STEInfo mainInfo, STEInfo... updates) {
+        return assertDeclareFail(input,
+                new ExpectedDiagnostic(expectedErrorCode, -1, -1, -1, -1, -1, Diagnostic.Kind.ERROR),
+                mainInfo, updates);
+    }
+
+    public Snippet assertDeclareFail(String input, ExpectedDiagnostic expectedDiagnostic) {
+        return assertDeclareFail(input, expectedDiagnostic, added(REJECTED));
+    }
+
+    public Snippet assertDeclareFail(String input, ExpectedDiagnostic expectedDiagnostic,
+            STEInfo mainInfo, STEInfo... updates) {
+        List<SnippetEvent> events = assertEval(input, null, null,
+                DiagCheck.DIAG_ERROR, DiagCheck.DIAG_IGNORE, mainInfo, updates);
+        SnippetEvent e = events.get(0);
+        Snippet key = e.snippet();
+        assertEquals(getState().status(key), REJECTED);
+        List<Diag> diagnostics = getState().diagnostics(e.snippet());
+        assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none");
+        assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
+        assertTrue(key != null, "key must never be null, but it was for: " + input);
+        return key;
+    }
+
+    public Snippet assertDeclareWarn1(String input, String expectedErrorCode) {
+        return assertDeclareWarn1(input, new ExpectedDiagnostic(expectedErrorCode, -1, -1, -1, -1, -1, Diagnostic.Kind.WARNING));
+    }
+
+    public Snippet assertDeclareWarn1(String input, ExpectedDiagnostic expectedDiagnostic) {
+        return assertDeclareWarn1(input, expectedDiagnostic, added(VALID));
+    }
+
+    public Snippet assertDeclareWarn1(String input, ExpectedDiagnostic expectedDiagnostic, STEInfo mainInfo, STEInfo... updates) {
+        List<SnippetEvent> events = assertEval(input, IGNORE_VALUE, null,
+                DiagCheck.DIAG_WARNING, DiagCheck.DIAG_IGNORE, mainInfo, updates);
+        SnippetEvent e = events.get(0);
+        List<Diag> diagnostics = getState().diagnostics(e.snippet());
+        assertDiagnostic(input, diagnostics.get(0), expectedDiagnostic);
+        return e.snippet();
+    }
+
+    private void assertDiagnostic(String input, Diag diagnostic, ExpectedDiagnostic expectedDiagnostic) {
+        if (expectedDiagnostic != null) expectedDiagnostic.assertDiagnostic(diagnostic);
+        // assertEquals(diagnostic.getSource(), input, "Diagnostic source");
+    }
+
+    public void assertTypeDeclSnippet(TypeDeclSnippet type, String expectedName,
+            Status expectedStatus, SubKind expectedSubKind,
+            int unressz, int othersz) {
+        assertDeclarationSnippet(type, expectedName, expectedStatus,
+                expectedSubKind, unressz, othersz);
+    }
+
+    public void assertMethodDeclSnippet(MethodSnippet method,
+            String expectedName, String expectedSignature,
+            Status expectedStatus, int unressz, int othersz) {
+        assertDeclarationSnippet(method, expectedName, expectedStatus,
+                METHOD_SUBKIND, unressz, othersz);
+        String signature = method.signature();
+        assertEquals(signature, expectedSignature,
+                "Expected " + method.source() + " to have the name: " +
+                        expectedSignature + ", got: " + signature);
+    }
+
+    public void assertVariableDeclSnippet(VarSnippet var,
+            String expectedName, String expectedTypeName,
+            Status expectedStatus, SubKind expectedSubKind,
+            int unressz, int othersz) {
+        assertDeclarationSnippet(var, expectedName, expectedStatus,
+                expectedSubKind, unressz, othersz);
+        String signature = var.typeName();
+        assertEquals(signature, expectedTypeName,
+                "Expected " + var.source() + " to have the name: " +
+                        expectedTypeName + ", got: " + signature);
+    }
+
+    public void assertDeclarationSnippet(DeclarationSnippet declarationKey,
+            String expectedName,
+            Status expectedStatus, SubKind expectedSubKind,
+            int unressz, int othersz) {
+        assertKey(declarationKey, expectedStatus, expectedSubKind);
+        String source = declarationKey.source();
+        assertEquals(declarationKey.name(), expectedName,
+                "Expected " + source + " to have the name: " + expectedName + ", got: " + declarationKey.name());
+        List<String> unresolved = getState().unresolvedDependencies(declarationKey);
+        assertEquals(unresolved.size(), unressz, "Expected " + source + " to have " + unressz
+                + " unresolved symbols, got: " + unresolved.size());
+        List<Diag> otherCorralledErrors = getState().diagnostics(declarationKey);
+        assertEquals(otherCorralledErrors.size(), othersz, "Expected " + source + " to have " + othersz
+                + " other errors, got: " + otherCorralledErrors.size());
+    }
+
+    public void assertKey(Snippet key, Status expectedStatus, SubKind expectedSubKind) {
+        String source = key.source();
+        SubKind actualSubKind = key.subKind();
+        assertEquals(actualSubKind, expectedSubKind,
+                "Expected " + source + " to have the subkind: " + expectedSubKind + ", got: " + actualSubKind);
+        Status status = getState().status(key);
+        assertEquals(status, expectedStatus, "Expected " + source + " to be "
+                + expectedStatus + ", but it is " + status);
+        Snippet.Kind expectedKind = getKind(key);
+        assertEquals(key.kind(), expectedKind, "Checking kind: ");
+        assertEquals(expectedSubKind.kind(), expectedKind, "Checking kind: ");
+    }
+
+    public void assertDrop(PersistentSnippet key, STEInfo mainInfo, STEInfo... updates) {
+        assertDrop(key, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, mainInfo, updates);
+    }
+
+    public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
+        assertDrop(key, diagMain, diagUpdates, new EventChain(mainInfo, null, null, updates));
+    }
+
+    public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
+        checkEvents(() -> getState().drop(key), "drop(" + key + ")", diagMain, diagUpdates, eventChains);
+    }
+
+    public void assertAnalyze(String input, String source, String remaining, boolean isComplete) {
+        assertAnalyze(input, null, source, remaining, isComplete);
+    }
+
+     public void assertAnalyze(String input, Completeness status, String source) {
+        assertAnalyze(input, status, source, null, null);
+    }
+
+    public void assertAnalyze(String input, Completeness status, String source, String remaining, Boolean isComplete) {
+        CompletionInfo ci = getAnalysis().analyzeCompletion(input);
+        if (status != null) assertEquals(ci.completeness, status, "Input : " + input + ", status: ");
+        if (source != null) assertEquals(ci.source, source, "Input : " + input + ", source: ");
+        if (remaining != null) assertEquals(ci.remaining, remaining, "Input : " + input + ", remaining: ");
+        if (isComplete != null) {
+            boolean isExpectedComplete = isComplete;
+            assertEquals(ci.completeness.isComplete, isExpectedComplete, "Input : " + input + ", isComplete: ");
+        }
+    }
+
+    public void assertNumberOfActiveVariables(int cnt) {
+        Collection<VarSnippet> variables = getState().variables();
+        assertEquals(variables.size(), cnt, "Variables : " + variables);
+    }
+
+    public void assertNumberOfActiveMethods(int cnt) {
+        Collection<MethodSnippet> methods = getState().methods();
+        assertEquals(methods.size(), cnt, "Methods : " + methods);
+    }
+
+    public void assertNumberOfActiveClasses(int cnt) {
+        Collection<TypeDeclSnippet> classes = getState().types();
+        assertEquals(classes.size(), cnt, "Classes : " + classes);
+    }
+
+    public void assertMembers(Collection<? extends Snippet> members, Set<MemberInfo> expected) {
+        assertEquals(members.size(), expected.size(), "Expected : " + expected + ", actual : " + members);
+        assertEquals(members.stream()
+                        .map(this::getMemberInfo)
+                        .collect(Collectors.toSet()),
+                expected);
+    }
+
+    public void assertKeys(MemberInfo... expected) {
+        int index = 0;
+        List<Snippet> snippets = getState().snippets();
+        assertEquals(allSnippets.size(), snippets.size());
+        for (Snippet sn : snippets) {
+            if (sn.kind().isPersistent && getState().status(sn).isActive) {
+                MemberInfo actual = getMemberInfo(sn);
+                MemberInfo exp = expected[index];
+                assertEquals(actual, exp, String.format("Difference in #%d. Expected: %s, actual: %s",
+                        index, exp, actual));
+                ++index;
+            }
+        }
+    }
+
+    public void assertActiveKeys() {
+        Collection<Snippet> expected = getActiveKeys();
+        assertActiveKeys(expected.toArray(new Snippet[expected.size()]));
+    }
+
+    public void assertActiveKeys(Snippet... expected) {
+        int index = 0;
+        for (Snippet key : getState().snippets()) {
+            if (state.status(key).isActive) {
+                assertEquals(expected[index], key, String.format("Difference in #%d. Expected: %s, actual: %s", index, key, expected[index]));
+                ++index;
+            }
+        }
+    }
+
+    private List<Snippet> filterDeclaredKeys(Predicate<Snippet> p) {
+        return getActiveKeys().stream()
+                .filter(p)
+                .collect(Collectors.toList());
+    }
+
+    public void assertVariables() {
+        assertEquals(getState().variables(), filterDeclaredKeys((key) -> key instanceof VarSnippet), "Variables");
+    }
+
+    public void assertMethods() {
+        assertEquals(getState().methods(), filterDeclaredKeys((key) -> key instanceof MethodSnippet), "Methods");
+    }
+
+    public void assertClasses() {
+        assertEquals(getState().types(), filterDeclaredKeys((key) -> key instanceof TypeDeclSnippet), "Classes");
+    }
+
+    public void assertVariables(MemberInfo...expected) {
+        assertMembers(getState().variables(), Stream.of(expected).collect(Collectors.toSet()));
+    }
+
+    public void assertMethods(MemberInfo...expected) {
+        assertMembers(getState().methods(), Stream.of(expected).collect(Collectors.toSet()));
+        for (MethodSnippet methodKey : getState().methods()) {
+            MemberInfo expectedInfo = null;
+            for (MemberInfo info : expected) {
+                if (info.name.equals(methodKey.name()) && info.type.equals(methodKey.signature())) {
+                    expectedInfo = getMemberInfo(methodKey);
+                }
+            }
+            assertNotNull(expectedInfo, "Not found method: " + methodKey.name());
+            int lastIndexOf = expectedInfo.type.lastIndexOf(')');
+            assertEquals(methodKey.parameterTypes(), expectedInfo.type.substring(1, lastIndexOf), "Parameter types");
+        }
+    }
+
+    public void assertClasses(MemberInfo...expected) {
+        assertMembers(getState().types(), Stream.of(expected).collect(Collectors.toSet()));
+    }
+
+    public void assertCompletion(String code, String... expected) {
+        assertCompletion(code, null, expected);
+    }
+
+    public void assertCompletion(String code, Boolean isSmart, String... expected) {
+        List<String> completions = computeCompletions(code, isSmart);
+        assertEquals(completions, Arrays.asList(expected), "Input: " + code + ", " + completions.toString());
+    }
+
+    public void assertCompletionIncludesExcludes(String code, Set<String> expected, Set<String> notExpected) {
+        assertCompletionIncludesExcludes(code, null, expected, notExpected);
+    }
+
+    public void assertCompletionIncludesExcludes(String code, Boolean isSmart, Set<String> expected, Set<String> notExpected) {
+        List<String> completions = computeCompletions(code, isSmart);
+        assertTrue(completions.containsAll(expected), String.valueOf(completions));
+        assertTrue(Collections.disjoint(completions, notExpected), String.valueOf(completions));
+    }
+
+    private List<String> computeCompletions(String code, Boolean isSmart) {
+        int cursor =  code.indexOf('|');
+        code = code.replace("|", "");
+        assertTrue(cursor > -1, "'|' expected, but not found in: " + code);
+        List<Suggestion> completions =
+                getAnalysis().completionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
+        return completions.stream()
+                          .filter(s -> isSmart == null || isSmart == s.isSmart)
+                          .map(s -> s.continuation)
+                          .distinct()
+                          .collect(Collectors.toList());
+    }
+
+    public void assertDocumentation(String code, String... expected) {
+        int cursor =  code.indexOf('|');
+        code = code.replace("|", "");
+        assertTrue(cursor > -1, "'|' expected, but not found in: " + code);
+        String documentation = getAnalysis().documentation(code, cursor);
+        Set<String> docSet = Stream.of(documentation.split("\r?\n")).collect(Collectors.toSet());
+        Set<String> expectedSet = Stream.of(expected).collect(Collectors.toSet());
+        assertEquals(docSet, expectedSet, "Input: " + code);
+    }
+
+    public enum ClassType {
+        CLASS("CLASS_SUBKIND") {
+            @Override
+            public String toString() {
+                return "class";
+            }
+        },
+        ENUM("ENUM_SUBKIND") {
+            @Override
+            public String toString() {
+                return "enum";
+            }
+        },
+        INTERFACE("INTERFACE_SUBKIND") {
+            @Override
+            public String toString() {
+                return "interface";
+            }
+        },
+        ANNOTATION("ANNOTATION_TYPE_SUBKIND") {
+            @Override
+            public String toString() {
+                return "@interface";
+            }
+        };
+
+        private final String classType;
+
+        ClassType(String classType) {
+            this.classType = classType;
+        }
+
+        public String getClassType() {
+            return classType;
+        }
+
+        @Override
+        public abstract String toString();
+    }
+
+    public static MemberInfo variable(String type, String name) {
+        return new MemberInfo(type, name);
+    }
+
+    public static MemberInfo method(String signature, String name) {
+        return new MemberInfo(signature, name);
+    }
+
+    public static MemberInfo clazz(ClassType classType, String className) {
+        return new MemberInfo(classType.getClassType(), className);
+    }
+
+    public static class MemberInfo {
+        public final String type;
+        public final String name;
+
+        public MemberInfo(String type, String name) {
+            this.type = type;
+            this.name = name;
+        }
+
+        @Override
+        public int hashCode() {
+            return type.hashCode() + 3 * name.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof MemberInfo) {
+                MemberInfo other = (MemberInfo) o;
+                return type.equals(other.type) && name.equals(other.name);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s %s", type, name);
+        }
+    }
+
+    public MemberInfo getMemberInfo(Snippet key) {
+        SubKind subkind = key.subKind();
+        switch (subkind) {
+            case CLASS_SUBKIND:
+            case INTERFACE_SUBKIND:
+            case ENUM_SUBKIND:
+            case ANNOTATION_TYPE_SUBKIND:
+                return new MemberInfo(subkind.name(), ((DeclarationSnippet) key).name());
+            case METHOD_SUBKIND:
+                MethodSnippet method = (MethodSnippet) key;
+                return new MemberInfo(method.signature(), method.name());
+            case VAR_DECLARATION_SUBKIND:
+            case VAR_DECLARATION_WITH_INITIALIZER_SUBKIND:
+            case TEMP_VAR_EXPRESSION_SUBKIND:
+                VarSnippet var = (VarSnippet) key;
+                return new MemberInfo(var.typeName(), var.name());
+            default:
+                throw new AssertionError("Unknown snippet : " + key.kind() + " in expression " + key.toString());
+        }
+    }
+
+    public String diagnosticsToString(List<Diag> diagnostics) {
+        StringWriter writer = new StringWriter();
+        for (Diag diag : diagnostics) {
+            writer.write("Error --\n");
+            for (String line : diag.getMessage(null).split("\\r?\\n")) {
+                writer.write(String.format("%s\n", line));
+            }
+        }
+        return writer.toString().replace("\n", System.lineSeparator());
+    }
+
+    public boolean hasFatalError(List<Diag> diagnostics) {
+        for (Diag diag : diagnostics) {
+            if (diag.isError()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static EventChain chain(STEInfo mainInfo, STEInfo... updates) {
+        return chain(mainInfo, IGNORE_VALUE, null, updates);
+    }
+
+    public static EventChain chain(STEInfo mainInfo, String value, Class<? extends Throwable> exceptionClass, STEInfo... updates) {
+        return new EventChain(mainInfo, value, exceptionClass, updates);
+    }
+
+    public static STEInfo ste(Snippet key, Status previousStatus, Status status,
+                Boolean isSignatureChange, Snippet causeKey) {
+        return new STEInfo(key, previousStatus, status, isSignatureChange, causeKey);
+    }
+
+    public static STEInfo added(Status status) {
+        return new STEInfo(MAIN_SNIPPET, NONEXISTENT, status, status.isDefined, null);
+    }
+
+    public static class EventChain {
+        public final STEInfo mainInfo;
+        public final STEInfo[] updates;
+        public final String value;
+        public final Class<? extends Throwable> exceptionClass;
+
+        public EventChain(STEInfo mainInfo, String value, Class<? extends Throwable> exceptionClass, STEInfo... updates) {
+            this.mainInfo = mainInfo;
+            this.updates = updates;
+            this.value = value;
+            this.exceptionClass = exceptionClass;
+        }
+    }
+
+    public static class STEInfo {
+
+        STEInfo(Snippet snippet, Status previousStatus, Status status,
+                Boolean isSignatureChange, Snippet causeSnippet) {
+            this.snippet = snippet;
+            this.previousStatus = previousStatus;
+            this.status = status;
+            this.checkIsSignatureChange = isSignatureChange != null;
+            this.isSignatureChange = checkIsSignatureChange ? isSignatureChange : false;
+            this.causeSnippet = causeSnippet;
+            assertTrue(snippet != null, "Bad test set-up. The match snippet must not be null");
+        }
+
+        final Snippet snippet;
+        final Status previousStatus;
+        final Status status;
+        final boolean isSignatureChange;
+        final Snippet causeSnippet;
+
+         final boolean checkIsSignatureChange;
+        public Snippet snippet() {
+            return snippet;
+        }
+        public Status previousStatus() {
+            return previousStatus;
+        }
+        public Status status() {
+            return status;
+        }
+        public boolean isSignatureChange() {
+            if (!checkIsSignatureChange) {
+                throw new IllegalStateException("isSignatureChange value is undefined");
+            }
+            return isSignatureChange;
+        }
+        public Snippet causeSnippet() {
+            return causeSnippet;
+        }
+        public String value() {
+            return null;
+        }
+        public Exception exception() {
+            return null;
+        }
+
+        public void assertMatch(SnippetEvent ste, Snippet mainSnippet) {
+            assertKeyMatch(ste, ste.snippet(), snippet(), mainSnippet);
+            assertStatusMatch(ste, ste.previousStatus(), previousStatus());
+            assertStatusMatch(ste, ste.status(), status());
+            if (checkIsSignatureChange) {
+                assertEquals(ste.isSignatureChange(), isSignatureChange(),
+                        "Expected " +
+                                (isSignatureChange()? "" : "no ") +
+                                "signature-change, got: " +
+                                (ste.isSignatureChange()? "" : "no ") +
+                                "signature-change" +
+                        "\n   expected-event: " + this + "\n   got-event: " + toString(ste));
+            }
+            assertKeyMatch(ste, ste.causeSnippet(), causeSnippet(), mainSnippet);
+        }
+
+        private void assertKeyMatch(SnippetEvent ste, Snippet sn, Snippet expected, Snippet mainSnippet) {
+            Snippet testKey = expected;
+            if (testKey != null) {
+                if (expected == MAIN_SNIPPET) {
+                    assertNotNull(mainSnippet, "MAIN_SNIPPET used, test must pass value to assertMatch");
+                    testKey = mainSnippet;
+                }
+                if (ste.causeSnippet() == null && ste.status() != DROPPED && expected != MAIN_SNIPPET) {
+                    // Source change, always new snippet -- only match id()
+                    assertTrue(sn != testKey,
+                            "Main-event: Expected new snippet to be != : " + testKey
+                            + "\n   got-event: " + toString(ste));
+                    assertEquals(sn.id(), testKey.id(), "Expected IDs to match: " + testKey + ", got: " + sn
+                            + "\n   expected-event: " + this + "\n   got-event: " + toString(ste));
+                } else {
+                    assertEquals(sn, testKey, "Expected key to be: " + testKey + ", got: " + sn
+                            + "\n   expected-event: " + this + "\n   got-event: " + toString(ste));
+                }
+            }
+        }
+
+        private void assertStatusMatch(SnippetEvent ste, Status status, Status expected) {
+            if (expected != null) {
+                assertEquals(status, expected, "Expected status to be: " + expected + ", got: " + status +
+                        "\n   expected-event: " + this + "\n   got-event: " + toString(ste));
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "STEInfo key: " +
+                    (snippet()==MAIN_SNIPPET? "MAIN_SNIPPET" : (snippet()==null? "ignore" : snippet().id())) +
+                    " before: " + previousStatus() +
+                    " status: " + status() + " sig: " + isSignatureChange() +
+                    " cause: " + (causeSnippet()==null? "null" : causeSnippet().id());
+        }
+
+        private String toString(SnippetEvent ste) {
+            return "key: " + (ste.snippet()==MAIN_SNIPPET? "MAIN_SNIPPET" : ste.snippet().id()) + " before: " + ste.previousStatus()
+                    + " status: " + ste.status() + " sig: " + ste.isSignatureChange()
+                    + " cause: " + ste.causeSnippet();
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/MethodsTest.java b/langtools/test/jdk/jshell/MethodsTest.java
new file mode 100644
index 0000000..28eec73
--- /dev/null
+++ b/langtools/test/jdk/jshell/MethodsTest.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for EvaluationState.methods
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic
+ * @run testng MethodsTest
+ */
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Snippet;
+import jdk.jshell.MethodSnippet;
+import jdk.jshell.Snippet.Status;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.*;
+import static jdk.jshell.Snippet.SubKind.*;
+
+@Test
+public class MethodsTest extends KullaTesting {
+
+    public void noMethods() {
+        assertNumberOfActiveMethods(0);
+    }
+
+    public void testSignature1() {
+        MethodSnippet m1 = methodKey(assertEval("void f() { g(); }", added(RECOVERABLE_DEFINED)));
+        assertMethodDeclSnippet(m1, "f", "()void", RECOVERABLE_DEFINED, 1, 0);
+        MethodSnippet m2 = methodKey(assertEval("void g() { }",
+                added(VALID),
+                ste(m1, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertMethodDeclSnippet(m2, "g", "()void", VALID, 0, 0);
+    }
+
+    public void testSignature2() {
+        MethodSnippet m1 = (MethodSnippet) assertDeclareFail("void f() { return g(); }", "compiler.err.prob.found.req");
+        assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
+        MethodSnippet m2 = methodKey(assertEval("int f() { return g(); }",
+                ste(m1, REJECTED, RECOVERABLE_DEFINED, true, null)));
+        assertMethodDeclSnippet(m1, "f", "()void", REJECTED, 0, 2);
+        assertMethodDeclSnippet(m2, "f", "()int", RECOVERABLE_DEFINED, 1, 0);
+    }
+
+    @Test(enabled = false) // TODO 8081690
+    public void testSignature3() {
+        MethodSnippet m1 = methodKey(assertEval("void f(Bar b) { }", added(RECOVERABLE_NOT_DEFINED)));
+        assertMethodDeclSnippet(m1, "f", "(Bar)void", RECOVERABLE_NOT_DEFINED, 1, 0);
+        MethodSnippet m2 = methodKey(assertEval("void f(A.Bar b) { }", added(RECOVERABLE_NOT_DEFINED)));
+        assertMethodDeclSnippet(m1, "f", "(Bar)void", RECOVERABLE_NOT_DEFINED, 1, 0);
+        assertMethodDeclSnippet(m2, "f", "(A.Bar)void", RECOVERABLE_NOT_DEFINED, 1, 0);
+        assertDrop(m1, ste(m1, RECOVERABLE_NOT_DEFINED, DROPPED, false, null));
+        assertMethodDeclSnippet(m1, "f", "(Bar)void", DROPPED, 1, 0);
+    }
+
+    public void methods() {
+        assertEval("int x() { return 10; }");
+        assertEval("String y() { return null; }");
+        assertEval("long z() { return 0; }");
+        assertMethods(method("()int", "x"), method("()String", "y"), method("()long", "z"));
+        assertActiveKeys();
+    }
+
+    public void methodOverload() {
+        assertEval("int m() { return 1; }");
+        assertEval("int m(int x) { return 2; }");
+        assertEval("int m(String s) { return 3; }");
+        assertEval("int m(int x, int y) { return 4; }");
+        assertEval("int m(int x, String z) { return 5; }");
+        assertEval("int m(int x, String z, long g) { return 6; }");
+        assertMethods(
+                method("()int", "m"),
+                method("(int)int", "m"),
+                method("(String)int", "m"),
+                method("(int,int)int", "m"),
+                method("(int,String)int", "m"),
+                method("(int,String,long)int", "m")
+        );
+        assertEval("m();", "1");
+        assertEval("m(3);", "2");
+        assertEval("m(\"hi\");", "3");
+        assertEval("m(7, 8);", "4");
+        assertEval("m(7, \"eight\");", "5");
+        assertEval("m(7, \"eight\", 9L);", "6");
+        assertActiveKeys();
+    }
+
+    public void methodsRedeclaration1() {
+        Snippet x = methodKey(assertEval("int x() { return 10; }"));
+        Snippet y = methodKey(assertEval("String y() { return \"\"; }"));
+        assertMethods(method("()int", "x"), method("()String", "y"));
+        assertActiveKeys();
+
+        assertEval("long x() { return 0; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertMethods(method("()long", "x"), method("()String", "y"));
+        assertActiveKeys();
+
+        assertEval("String y() { return null; }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(y, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertMethods(method("()long", "x"), method("()String", "y"));
+        assertActiveKeys();
+    }
+
+    public void methodsRedeclaration2() {
+        assertEval("int a() { return 1; }");
+        assertMethods(method("()int", "a"));
+        assertActiveKeys();
+
+        Snippet b = methodKey(assertEval("Integer b() { return a(); }"));
+        assertMethods(method("()int", "a"), method("()Integer", "b"));
+        assertActiveKeys();
+
+        Snippet c = methodKey(assertEval("double c() { return b(); }"));
+        assertMethods(method("()int", "a"), method("()Integer", "b"), method("()double", "c"));
+        assertActiveKeys();
+
+        assertEval("double b() { return 3.14159; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(c, VALID, VALID, false, MAIN_SNIPPET));
+        assertMethods(method("()int", "a"), method("()double", "b"), method("()double", "c"));
+        assertEval("c();", "3.14159");
+        assertActiveKeys();
+    }
+
+    public void methodsRedeclaration3() {
+        Snippet x = methodKey(assertEval("int x(Object...a) { return 10; }"));
+        assertMethods(method("(Object...)int", "x"));
+        assertActiveKeys();
+
+        assertEval("int x(Object[]a) { return 10; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertMethods(method("(Object[])int", "x"));
+        assertActiveKeys();
+    }
+
+
+    public void methodsRedeclaration4() {
+        Snippet a = methodKey(assertEval("int foo(int a) { return a; }"));
+        assertEval("int x = foo(10);");
+        assertActiveKeys();
+        assertMethods(method("(int)int", "foo"));
+        assertEval("int foo(int a) { return a * a; }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertActiveKeys();
+    }
+
+    public void methodsErrors() {
+        assertDeclareFail("String f();",
+                new ExpectedDiagnostic("compiler.err.missing.meth.body.or.decl.abstract", 0, 11, 7, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertDeclareFail("abstract String f();",
+                new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 8, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertDeclareFail("native String f();",
+                new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertDeclareFail("synchronized String f() {return null;}",
+                new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 12, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertDeclareFail("int f() {}", "compiler.err.missing.ret.stmt",
+                ste(MAIN_SNIPPET, REJECTED, REJECTED, false, null));
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+
+        assertEval("String x() { return \"\"; };");
+        assertMethods(method("()String", "x"));
+        assertActiveKeys();
+    }
+
+    public void methodsWarn() {
+        Snippet f = assertDeclareWarn1("public String f() {return null;}",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
+                added(VALID));
+        assertNumberOfActiveMethods(1);
+        assertActiveKeys();
+
+        f = assertDeclareWarn1("protected String f() {return null;}",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING),
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertNumberOfActiveMethods(1);
+        assertActiveKeys();
+
+        f = assertDeclareWarn1("private String f() {return null;}",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 7, 0, -1, -1, Diagnostic.Kind.WARNING),
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertNumberOfActiveMethods(1);
+        assertActiveKeys();
+
+        f = assertDeclareWarn1("static String f() {return null;}",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertNumberOfActiveMethods(1);
+        assertActiveKeys();
+
+        assertDeclareWarn1("final String f() {return null;}",
+                new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 5, 0, -1, -1, Diagnostic.Kind.WARNING),
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertNumberOfActiveMethods(1);
+        assertActiveKeys();
+    }
+
+    public void methodSignatureUnresolved() {
+        MethodSnippet key = (MethodSnippet) methodKey(assertEval("und m() { return new und(); }", added(RECOVERABLE_NOT_DEFINED)));
+        assertMethodDeclSnippet(key, "m", "()und", RECOVERABLE_NOT_DEFINED, 1, 0);
+        assertUnresolvedDependencies1(key, Status.RECOVERABLE_NOT_DEFINED, "class und");
+        assertEval("class und {}",
+                added(VALID),
+                ste(key, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertMethodDeclSnippet(key, "m", "()und", Status.VALID, 0, 0);
+        assertNumberOfActiveMethods(1);
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081689
+    public void classMethodsAreNotVisible() {
+        assertEval(
+            "class A {" +
+                "int foo() {" +
+                    "int x = 10;" +
+                    "int y = 2 * x;" +
+                    "return x * y;" +
+                "}" +
+            "}");
+        assertNumberOfActiveMethods(0);
+        assertEval("int x = 10;", "10");
+        assertEval("int foo() {" +
+                        "int y = 2 * x;" +
+                        "return x * y;" +
+                        "}");
+        assertMethods(method("()int", "foo"));
+        assertEval("foo();", "200");
+        assertActiveKeys();
+    }
+
+    public void lambdas() {
+        assertEval("class Inner1 implements Runnable {" +
+                "public Runnable lambda1 = () -> {};" +
+                "public void function() {}" +
+                "public void run() {}" +
+                "}");
+
+        assertEval("class Inner2 {" +
+                "private Runnable lambda1 = () -> {};" +
+                "private static void staticFunction() {}" +
+                "}");
+
+        // the following method references and lambda functions
+        // generate synthetic methods
+        assertEval("Runnable run = () -> {};");
+        assertEval("Inner1 inner = new Inner1();");
+        assertEval("Runnable l1 = inner::function;");
+        assertEval("Runnable l2 = Inner1::new;");
+        assertEval("inner.lambda1 = inner::function;");
+        assertEval("java.util.stream.IntStream.of(2).mapToObj(int[]::new);");
+        assertNumberOfActiveMethods(0);
+        assertActiveKeys();
+    }
+}
diff --git a/langtools/test/jdk/jshell/ModifiersTest.java b/langtools/test/jdk/jshell/ModifiersTest.java
new file mode 100644
index 0000000..8f7cdf2
--- /dev/null
+++ b/langtools/test/jdk/jshell/ModifiersTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for modifiers
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic
+ * @run testng ModifiersTest
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test
+public class ModifiersTest extends KullaTesting {
+
+    @DataProvider(name = "ignoredModifiers")
+    public Object[][] getTestCases() {
+        List<Object[]> testCases = new ArrayList<>();
+        String[] ignoredModifiers = new String[] {
+            "public", "protected", "private", "static", "final"
+        };
+        for (String ignoredModifier : ignoredModifiers) {
+            for (ClassType classType : ClassType.values()) {
+                testCases.add(new Object[] { ignoredModifier, classType });
+            }
+        }
+        return testCases.toArray(new Object[testCases.size()][]);
+    }
+
+    @Test(dataProvider = "ignoredModifiers")
+    public void ignoredModifiers(String modifier, ClassType classType) {
+        assertDeclareWarn1(
+                String.format("%s %s A {}", modifier, classType), "jdk.eval.warn.illegal.modifiers");
+        assertNumberOfActiveClasses(1);
+        assertClasses(clazz(classType, "A"));
+        assertActiveKeys();
+    }
+
+    public void accessToStaticFieldsOfClass() {
+        assertEval("class A {" +
+                "int x = 14;" +
+                "static int y = 18;" +
+                " }");
+        assertDeclareFail("A.x;",
+                new ExpectedDiagnostic("compiler.err.non-static.cant.be.ref", 0, 3, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertEval("A.y;", "18");
+        assertEval("new A().x;", "14");
+        assertEval("A.y = 88;", "88");
+        assertActiveKeys();
+    }
+
+    public void accessToStaticMethodsOfClass() {
+        assertEval("class A {" +
+                "void x() {}" +
+                "static void y() {}" +
+                " }");
+        assertDeclareFail("A.x();",
+                new ExpectedDiagnostic("compiler.err.non-static.cant.be.ref", 0, 3, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertEval("A.y();");
+        assertActiveKeys();
+    }
+
+    public void accessToStaticFieldsOfInterface() {
+        assertEval("interface A {" +
+                "int x = 14;" +
+                "static int y = 18;" +
+                " }");
+        assertEval("A.x;", "14");
+        assertEval("A.y;", "18");
+
+        assertDeclareFail("A.x = 18;",
+                new ExpectedDiagnostic("compiler.err.cant.assign.val.to.final.var", 0, 3, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertDeclareFail("A.y = 88;",
+                new ExpectedDiagnostic("compiler.err.cant.assign.val.to.final.var", 0, 3, 1, -1, -1, Diagnostic.Kind.ERROR));
+        assertActiveKeys();
+    }
+
+    public void accessToStaticMethodsOfInterface() {
+        assertEval("interface A { static void x() {} }");
+        assertEval("A.x();");
+        assertActiveKeys();
+    }
+
+    public void finalMethod() {
+        assertEval("class A { final void f() {} }");
+        assertDeclareFail("class B extends A { void f() {} }",
+                new ExpectedDiagnostic("compiler.err.override.meth", 20, 31, 25, -1, -1, Diagnostic.Kind.ERROR));
+        assertActiveKeys();
+    }
+
+    //TODO: is this the right semantics?
+    public void finalConstructor() {
+        assertDeclareFail("class A { final A() {} }",
+                new ExpectedDiagnostic("compiler.err.mod.not.allowed.here", 10, 22, 16, -1, -1, Diagnostic.Kind.ERROR));
+        assertActiveKeys();
+    }
+
+    //TODO: is this the right semantics?
+    public void finalDefaultMethod() {
+        assertDeclareFail("interface A { final default void a() {} }",
+                new ExpectedDiagnostic("compiler.err.mod.not.allowed.here", 14, 39, 33, -1, -1, Diagnostic.Kind.ERROR));
+        assertActiveKeys();
+    }
+}
diff --git a/langtools/test/jdk/jshell/NullTest.java b/langtools/test/jdk/jshell/NullTest.java
new file mode 100644
index 0000000..b365b51
--- /dev/null
+++ b/langtools/test/jdk/jshell/NullTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 null test
+ * @build KullaTesting TestingInputStream
+ * @run testng NullTest
+ */
+
+import org.testng.annotations.Test;
+
+@Test
+public class NullTest extends KullaTesting {
+
+    public void testNull() {
+        assertEval("null;", "null");
+        assertEval("(Object)null;", "null");
+        assertEval("(String)null;", "null");
+    }
+}
diff --git a/langtools/test/jdk/jshell/RejectedFailedTest.java b/langtools/test/jdk/jshell/RejectedFailedTest.java
new file mode 100644
index 0000000..d66c389
--- /dev/null
+++ b/langtools/test/jdk/jshell/RejectedFailedTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for hard errors, like syntax errors
+ * @build KullaTesting
+ * @run testng RejectedFailedTest
+ */
+
+import java.util.List;
+
+import jdk.jshell.Snippet.SubKind;
+import org.testng.annotations.Test;
+
+import jdk.jshell.Diag;
+import jdk.jshell.Snippet;
+import jdk.jshell.Snippet.Kind;
+import jdk.jshell.Snippet.Status;
+
+import jdk.jshell.SnippetEvent;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class RejectedFailedTest extends KullaTesting {
+
+    private String bad(String input, Kind kind, String prevId) {
+        List<SnippetEvent> events = assertEvalFail(input);
+        assertEquals(events.size(), 1, "Expected one event, got: " + events.size());
+        SnippetEvent e = events.get(0);
+        List<Diag> diagnostics = getState().diagnostics(e.snippet());
+        assertTrue(diagnostics.size() > 0, "Expected diagnostics, got none");
+        assertEquals(e.exception(), null, "Expected exception to be null.");
+        assertEquals(e.value(), null, "Expected value to be null.");
+
+        Snippet key = e.snippet();
+        assertTrue(key != null, "key must be non-null, but was null.");
+        assertEquals(key.kind(), kind, "Expected kind: " + kind + ", got: " + key.kind());
+        SubKind expectedSubKind = kind == Kind.ERRONEOUS ? SubKind.UNKNOWN_SUBKIND : SubKind.METHOD_SUBKIND;
+        assertEquals(key.subKind(), expectedSubKind, "SubKind: ");
+        assertTrue(key.id().compareTo(prevId) > 0, "Current id: " + key.id() + ", previous: " + prevId);
+        assertEquals(getState().diagnostics(key), diagnostics, "Expected retrieved diagnostics to match, but didn't.");
+        assertEquals(key.source(), input, "Expected retrieved source: " +
+                key.source() + " to match input: " + input);
+        assertEquals(getState().status(key), Status.REJECTED, "Expected status of REJECTED, got: " + getState().status(key));
+        return key.id();
+    }
+
+    private void checkByKind(String[] inputs, Kind kind) {
+        String prevId = "";
+        for (String in : inputs) {
+            prevId = bad(in, kind, prevId);
+        }
+    }
+
+    public void testErroneous() {
+        String[] inputsErroneous = {
+                "%&^%&",
+                " a b c",
+                ")",
+                "class interface A",
+        };
+        checkByKind(inputsErroneous, Kind.ERRONEOUS);
+    }
+
+    public void testBadMethod() {
+        String[] inputsMethod = {
+                "transient int m() { return x; }",
+                "int h() { }",
+                "void l() { return 4; }",
+                "int vv(void x) { return 2; }",
+        };
+        checkByKind(inputsMethod, Kind.METHOD);
+    }
+}
diff --git a/langtools/test/jdk/jshell/ReplToolTesting.java b/langtools/test/jdk/jshell/ReplToolTesting.java
new file mode 100644
index 0000000..cd07af1
--- /dev/null
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.internal.jshell.tool.JShellTool;
+import jdk.jshell.SourceCodeAnalysis.Suggestion;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+public class ReplToolTesting {
+
+    private final static String DEFAULT_STARTUP_MESSAGE = "|  Welcome to";
+
+    private WaitingTestingInputStream cmdin = null;
+    private ByteArrayOutputStream cmdout = null;
+    private ByteArrayOutputStream cmderr = null;
+    private PromptedCommandOutputStream console = null;
+    private TestingInputStream userin = null;
+    private ByteArrayOutputStream userout = null;
+    private ByteArrayOutputStream usererr = null;
+
+    private List<MemberInfo> keys;
+    private Map<String, VariableInfo> variables;
+    private Map<String, MethodInfo> methods;
+    private Map<String, ClassInfo> classes;
+    private boolean isDefaultStartUp = true;
+
+    public JShellTool repl = null;
+
+    public interface ReplTest {
+        void run(boolean after);
+    }
+
+    public void setCommandInput(String s) {
+        cmdin.setInput(s);
+    }
+
+    public final static Pattern idPattern = Pattern.compile("^\\s+(\\d+)");
+    public Consumer<String> assertList() {
+        return s -> {
+            List<String> lines = Stream.of(s.split("\n"))
+                    .filter(l -> !l.isEmpty())
+                    .collect(Collectors.toList());
+            int previousId = Integer.MIN_VALUE;
+            assertEquals(lines.size(), keys.size(), "Number of keys");
+            for (int i = 0; i < lines.size(); ++i) {
+                String line = lines.get(i);
+                Matcher matcher = idPattern.matcher(line);
+                assertTrue(matcher.find(), "Snippet id not found: " + line);
+                String src = keys.get(i).getSource();
+                assertTrue(line.endsWith(src), "Line '" + line + "' does not end with: " + src);
+                int id = Integer.parseInt(matcher.group(1));
+                assertTrue(previousId < id,
+                        String.format("The previous id is not less than the next one: previous: %d, next: %d",
+                                previousId, id));
+                previousId = id;
+            }
+        };
+    }
+
+    private final static Pattern extractPattern = Pattern.compile("^\\| *(.*)$");
+    private Consumer<String> assertMembers(String message, Map<String, ? extends MemberInfo> set) {
+        return s -> {
+            List<String> lines = Stream.of(s.split("\n"))
+                    .filter(l -> !l.isEmpty())
+                    .collect(Collectors.toList());
+            assertEquals(lines.size(), set.size(), message + " : expected: " + set.keySet() + "\ngot:\n" + lines);
+            for (String line : lines) {
+                Matcher matcher = extractPattern.matcher(line);
+                assertTrue(matcher.find(), line);
+                String src = matcher.group(1);
+                MemberInfo info = set.get(src);
+                assertNotNull(info, "Not found snippet with signature: " + src + ", line: "
+                        + line + ", keys: " + set.keySet() + "\n");
+            }
+        };
+    }
+
+    public Consumer<String> assertVariables() {
+        return assertMembers("Variables", variables);
+    }
+
+    public Consumer<String> assertMethods() {
+        return assertMembers("Methods", methods);
+    }
+
+    public Consumer<String> assertClasses() {
+        return assertMembers("Classes", classes);
+    }
+
+    public String getCommandOutput() {
+        String s = cmdout.toString();
+        cmdout.reset();
+        return s;
+    }
+
+    public String getCommandErrorOutput() {
+        String s = cmderr.toString();
+        cmderr.reset();
+        return s;
+    }
+
+    public void setUserInput(String s) {
+        userin.setInput(s);
+    }
+
+    public String getUserOutput() {
+        String s = userout.toString();
+        userout.reset();
+        return s;
+    }
+
+    public String getUserErrorOutput() {
+        String s = usererr.toString();
+        usererr.reset();
+        return s;
+    }
+
+    public void test(ReplTest... tests) {
+        test(new String[0], tests);
+    }
+
+    public void test(String[] args, ReplTest... tests) {
+        test(true, args, tests);
+    }
+
+    public void test(boolean isDefaultStartUp, String[] args, ReplTest... tests) {
+        test(isDefaultStartUp, args, DEFAULT_STARTUP_MESSAGE, tests);
+    }
+
+    public void test(boolean isDefaultStartUp, String[] args, String startUpMessage, ReplTest... tests) {
+        this.isDefaultStartUp = isDefaultStartUp;
+        initSnippets();
+        ReplTest[] wtests = new ReplTest[tests.length + 3];
+        wtests[0] = a -> assertCommandCheckOutput(a, "<start>",
+                s -> assertTrue(s.startsWith(startUpMessage), "Expected start-up message '" + startUpMessage + "' Got: " + s));
+        wtests[1] = a -> assertCommand(a, "/debug 0", null);
+        System.arraycopy(tests, 0, wtests, 2, tests.length);
+        wtests[tests.length + 2] = a -> assertCommand(a, "/exit", null);
+        testRaw(args, wtests);
+    }
+
+    private void initSnippets() {
+        keys = new ArrayList<>();
+        variables = new HashMap<>();
+        methods = new HashMap<>();
+        classes = new HashMap<>();
+        if (isDefaultStartUp) {
+            methods.put("printf (String,Object...)void",
+                    new MethodInfo("", "(String,Object...)void", "printf"));
+        }
+    }
+
+    public void testRaw(String[] args, ReplTest... tests) {
+        cmdin = new WaitingTestingInputStream();
+        cmdout = new ByteArrayOutputStream();
+        cmderr = new ByteArrayOutputStream();
+        console = new PromptedCommandOutputStream(tests);
+        userin = new TestingInputStream();
+        userout = new ByteArrayOutputStream();
+        usererr = new ByteArrayOutputStream();
+        repl = new JShellTool(
+                cmdin,
+                new PrintStream(cmdout),
+                new PrintStream(cmderr),
+                new PrintStream(console),
+                userin,
+                new PrintStream(userout),
+                new PrintStream(usererr));
+        repl.testPrompt = true;
+        try {
+            repl.start(args);
+        } catch (Exception ex) {
+            fail("Repl tool died with exception", ex);
+        }
+        // perform internal consistency checks on state, if desired
+        String cos = getCommandOutput();
+        String ceos = getCommandErrorOutput();
+        String uos = getUserOutput();
+        String ueos = getUserErrorOutput();
+        assertTrue((cos.isEmpty() || cos.startsWith("|  Goodbye")),
+                "Expected a goodbye, but got: " + cos);
+        assertTrue(ceos.isEmpty(), "Expected empty error output, got: " + ceos);
+        assertTrue(uos.isEmpty(), "Expected empty output, got: " + uos);
+        assertTrue(ueos.isEmpty(), "Expected empty error output, got: " + ueos);
+    }
+
+    public void assertReset(boolean after, String cmd) {
+        assertCommand(after, cmd, "|  Resetting state.\n");
+        initSnippets();
+    }
+
+    public void evaluateExpression(boolean after, String type, String expr, String value) {
+        String output = String.format("\\| *Expression values is: %s\n|" +
+                " *.*temporary variable (\\$\\d+) of type %s", value, type);
+        Pattern outputPattern = Pattern.compile(output);
+        assertCommandCheckOutput(after, expr, s -> {
+            Matcher matcher = outputPattern.matcher(s);
+            assertTrue(matcher.find(), "Output: '" + s + "' does not fit pattern: '" + output + "'");
+            String name = matcher.group(1);
+            VariableInfo tempVar = new TempVariableInfo(expr, type, name, value);
+            variables.put(tempVar.toString(), tempVar);
+            addKey(after, tempVar);
+        });
+    }
+
+    public void loadVariable(boolean after, String type, String name) {
+        loadVariable(after, type, name, null, null);
+    }
+
+    public void loadVariable(boolean after, String type, String name, String expr, String value) {
+        String src = expr == null
+                ? String.format("%s %s", type, name)
+                : String.format("%s %s = %s", type, name, expr);
+        VariableInfo var = expr == null
+                ? new VariableInfo(src, type, name)
+                : new VariableInfo(src, type, name, value);
+        addKey(after, var, variables);
+        addKey(after, var);
+    }
+
+    public void assertVariable(boolean after, String type, String name) {
+        assertVariable(after, type, name, null, null);
+    }
+
+    public void assertVariable(boolean after, String type, String name, String expr, String value) {
+        String src = expr == null
+                ? String.format("%s %s", type, name)
+                : String.format("%s %s = %s", type, name, expr);
+        VariableInfo var = expr == null
+                ? new VariableInfo(src, type, name)
+                : new VariableInfo(src, type, name, value);
+        assertCommandCheckOutput(after, src, var.checkOutput());
+        addKey(after, var, variables);
+        addKey(after, var);
+    }
+
+    public void loadMethod(boolean after, String src, String signature, String name) {
+        MethodInfo method = new MethodInfo(src, signature, name);
+        addKey(after, method, methods);
+        addKey(after, method);
+    }
+
+    public void assertMethod(boolean after, String src, String signature, String name) {
+        MethodInfo method = new MethodInfo(src, signature, name);
+        assertCommandCheckOutput(after, src, method.checkOutput());
+        addKey(after, method, methods);
+        addKey(after, method);
+    }
+
+    public void loadClass(boolean after, String src, String type, String name) {
+        ClassInfo clazz = new ClassInfo(src, type, name);
+        addKey(after, clazz, classes);
+        addKey(after, clazz);
+    }
+
+    public void assertClass(boolean after, String src, String type, String name) {
+        ClassInfo clazz = new ClassInfo(src, type, name);
+        assertCommandCheckOutput(after, src, clazz.checkOutput());
+        addKey(after, clazz, classes);
+        addKey(after, clazz);
+    }
+
+    private <T extends MemberInfo> void addKey(boolean after, T memberInfo, Map<String, T> map) {
+        if (after) {
+            map.entrySet().removeIf(e -> e.getValue().equals(memberInfo));
+            map.put(memberInfo.toString(), memberInfo);
+        }
+    }
+
+    private <T extends MemberInfo> void addKey(boolean after, T memberInfo) {
+        if (after) {
+            for (int i = 0; i < keys.size(); ++i) {
+                MemberInfo m = keys.get(i);
+                if (m.equals(memberInfo)) {
+                    keys.set(i, memberInfo);
+                    return;
+                }
+            }
+            keys.add(memberInfo);
+        }
+    }
+
+    private void dropKey(boolean after, String cmd, String name, Map<String, ? extends MemberInfo> map) {
+        assertCommand(after, cmd, "");
+        if (after) {
+            map.remove(name);
+            for (int i = 0; i < keys.size(); ++i) {
+                MemberInfo m = keys.get(i);
+                if (m.toString().equals(name)) {
+                    keys.remove(i);
+                    return;
+                }
+            }
+            throw new AssertionError("Key not found: " + name + ", keys: " + keys);
+        }
+    }
+
+    public void dropVariable(boolean after, String cmd, String name) {
+        dropKey(after, cmd, name, variables);
+    }
+
+    public void dropMethod(boolean after, String cmd, String name) {
+        dropKey(after, cmd, name, methods);
+    }
+
+    public void dropClass(boolean after, String cmd, String name) {
+        dropKey(after, cmd, name, classes);
+    }
+
+    public void assertCommand(boolean after, String cmd, String out) {
+        assertCommand(after, cmd, out, "", null, "", "");
+    }
+
+    public void assertCommandCheckOutput(boolean after, String cmd, Consumer<String> check) {
+        if (!after) {
+            assertCommand(false, cmd, null);
+        } else {
+            String got = getCommandOutput();
+            check.accept(got);
+            assertCommand(true, cmd, null);
+        }
+    }
+
+    public void assertCommand(boolean after, String cmd, String out, String err,
+            String userinput, String print, String usererr) {
+        if (!after) {
+            if (userinput != null) {
+                setUserInput(userinput);
+            }
+            setCommandInput(cmd + "\n");
+        } else {
+            assertOutput(getCommandOutput(), out, "command");
+            assertOutput(getCommandErrorOutput(), err, "command error");
+            assertOutput(getUserOutput(), print, "user");
+            assertOutput(getUserErrorOutput(), usererr, "user error");
+        }
+    }
+
+    public void assertCompletion(boolean after, String code, boolean isSmart, String... expected) {
+        if (!after) {
+            setCommandInput("\n");
+        } else {
+            assertCompletion(code, isSmart, expected);
+        }
+    }
+
+    public void assertCompletion(String code, boolean isSmart, String... expected) {
+        List<String> completions = computeCompletions(code, isSmart);
+        assertEquals(completions, Arrays.asList(expected), "Command: " + code + ", output: " +
+                completions.toString());
+    }
+
+    private List<String> computeCompletions(String code, boolean isSmart) {
+        JShellTool repl = this.repl != null ? this.repl
+                                      : new JShellTool(null, null, null, null, null, null, null);
+        int cursor =  code.indexOf('|');
+        code = code.replace("|", "");
+        assertTrue(cursor > -1, "'|' not found: " + code);
+        List<Suggestion> completions =
+                repl.commandCompletionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
+        return completions.stream()
+                          .filter(s -> isSmart == s.isSmart)
+                          .map(s -> s.continuation)
+                          .distinct()
+                          .collect(Collectors.toList());
+    }
+
+    public Consumer<String> assertStartsWith(String prefix) {
+        return (output) -> assertTrue(output.startsWith(prefix), "Output: \'" + output + "' does not start with: " + prefix);
+    }
+
+    public void assertOutput(String got, String expected, String kind) {
+        if (expected != null) {
+            assertEquals(got, expected, "Kind: " + kind + ".\n");
+        }
+    }
+
+    public static abstract class MemberInfo {
+        public final String source;
+        public final String type;
+        public final String name;
+
+        public MemberInfo(String source, String type, String name) {
+            this.source = source;
+            this.type = type;
+            this.name = name;
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        public abstract Consumer<String> checkOutput();
+
+        public String getSource() {
+            return source;
+        }
+    }
+
+    public static class VariableInfo extends MemberInfo {
+
+        public final String value;
+        public final String initialValue;
+
+        public VariableInfo(String src, String type, String name) {
+            super(src, type, name);
+            this.initialValue = null;
+            switch (type) {
+                case "byte":
+                case "short":
+                case "int":
+                case "long":
+                    value = "0";
+                    break;
+                case "boolean":
+                    value = "false";
+                    break;
+                case "char":
+                    value = "''";
+                    break;
+                case "float":
+                case "double":
+                    value = "0.0";
+                    break;
+                default:
+                    value = "null";
+            }
+        }
+
+        public VariableInfo(String src, String type, String name, String value) {
+            super(src, type, name);
+            this.value = value;
+            this.initialValue = value;
+        }
+
+        @Override
+        public Consumer<String> checkOutput() {
+            String pattern = String.format("\\| *\\w+ variable %s of type %s", name, type);
+            if (initialValue != null) {
+                pattern += " with initial value " + initialValue;
+            }
+            Predicate<String> checkOutput = Pattern.compile(pattern).asPredicate();
+            final String finalPattern = pattern;
+            return output -> assertTrue(checkOutput.test(output),
+                    "Output: " + output + " does not fit pattern: " + finalPattern);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof VariableInfo) {
+                VariableInfo v = (VariableInfo) o;
+                return name.equals(v.name);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s %s = %s", type, name, value);
+        }
+
+        @Override
+        public String getSource() {
+            String src = super.getSource();
+            return src.endsWith(";") ? src : src + ";";
+        }
+    }
+
+    public static class TempVariableInfo extends VariableInfo {
+
+        public TempVariableInfo(String src, String type, String name, String value) {
+            super(src, type, name, value);
+        }
+
+        @Override
+        public String getSource() {
+            return source;
+        }
+    }
+
+    public static class MethodInfo extends MemberInfo {
+
+        public final String signature;
+
+        public MethodInfo(String source, String signature, String name) {
+            super(source, signature.substring(0, signature.lastIndexOf(')') + 1), name);
+            this.signature = signature;
+        }
+
+        @Override
+        public Consumer<String> checkOutput() {
+            String expectedOutput = String.format("\\| *\\w+ method %s", name);
+            Predicate<String> checkOutput = Pattern.compile(expectedOutput).asPredicate();
+            return s -> assertTrue(checkOutput.test(s), "Expected: '" + expectedOutput + "', actual: " + s);
+        }
+
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof MemberInfo) {
+                MemberInfo m = (MemberInfo) o;
+                return name.equals(m.name) && type.equals(m.type);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s %s", name, signature);
+        }
+    }
+
+    public static class ClassInfo extends MemberInfo {
+
+        public ClassInfo(String source, String type, String name) {
+            super(source, type, name);
+        }
+
+        @Override
+        public Consumer<String> checkOutput() {
+            String fullType = type.equals("@interface")? "annotation interface" : type;
+            String expectedOutput = String.format("\\| *\\w+ %s %s", fullType, name);
+            Predicate<String> checkOutput = Pattern.compile(expectedOutput).asPredicate();
+            return s -> assertTrue(checkOutput.test(s), "Expected: '" + expectedOutput + "', actual: " + s);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof ClassInfo) {
+                ClassInfo c = (ClassInfo) o;
+                return name.equals(c.name);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s %s", type, name);
+        }
+    }
+
+    class WaitingTestingInputStream extends TestingInputStream {
+
+        @Override
+        synchronized void setInput(String s) {
+            super.setInput(s);
+            notify();
+        }
+
+        synchronized void waitForInput() {
+            boolean interrupted = false;
+            try {
+                while (available() == 0) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        interrupted = true;
+                        // fall through and retry
+                    }
+                }
+            } finally {
+                if (interrupted) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+        }
+
+        @Override
+        public int read() {
+            waitForInput();
+            return super.read();
+        }
+
+        @Override
+        public int read(byte b[], int off, int len) {
+            waitForInput();
+            return super.read(b, off, len);
+        }
+    }
+
+    class PromptedCommandOutputStream extends OutputStream {
+        private final ReplTest[] tests;
+        private int index = 0;
+        PromptedCommandOutputStream(ReplTest[] tests) {
+            this.tests = tests;
+        }
+
+        @Override
+        public synchronized void write(int b) {
+            if (b == 5 || b == 6) {
+                if (index < (tests.length - 1)) {
+                    tests[index].run(true);
+                    tests[index + 1].run(false);
+                } else {
+                    fail("Did not exit Repl tool after test");
+                }
+                ++index;
+            } // For now, anything else is thrown away
+        }
+
+        @Override
+        public synchronized void write(byte b[], int off, int len) {
+            if ((off < 0) || (off > b.length) || (len < 0)
+                    || ((off + len) - b.length > 0)) {
+                throw new IndexOutOfBoundsException();
+            }
+            for (int i = 0; i < len; ++i) {
+                write(b[off + i]);
+            }
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/ReplaceTest.java b/langtools/test/jdk/jshell/ReplaceTest.java
new file mode 100644
index 0000000..a26545d
--- /dev/null
+++ b/langtools/test/jdk/jshell/ReplaceTest.java
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 of Snippet redefinition and replacement.
+ * @build KullaTesting TestingInputStream
+ * @run testng ReplaceTest
+ */
+
+import java.util.Collection;
+
+import jdk.jshell.Snippet;
+import jdk.jshell.MethodSnippet;
+import jdk.jshell.PersistentSnippet;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.VarSnippet;
+import jdk.jshell.DeclarationSnippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.*;
+import static jdk.jshell.Snippet.SubKind.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ReplaceTest extends KullaTesting {
+
+    public void testRedefine() {
+        Snippet vx = varKey(assertEval("int x;"));
+        Snippet mu = methodKey(assertEval("int mu() { return x * 4; }"));
+        Snippet c = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
+        assertEval("C c0  = new C();");
+        assertEval("c0.v();", "\"#0\"");
+        assertEval("int x = 10;", "10",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(vx, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("c0.v();", "\"#40\"");
+        assertEval("C c = new C();");
+        assertEval("c.v();", "\"#40\"");
+        assertEval("int mu() { return x * 3; }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(mu, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("c.v();", "\"#30\"");
+        assertEval("class C { String v() { return \"@\" + mu(); } }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("c0.v();", "\"@30\"");
+        assertEval("c = new C();");
+        assertEval("c.v();", "\"@30\"");
+        assertActiveKeys();
+    }
+
+    public void testReplaceClassToVar() {
+        Snippet oldA = classKey(assertEval("class A { public String toString() { return \"old\"; } }"));
+        Snippet v = varKey(assertEval("A a = new A();", "old"));
+        assertEval("a;", "old");
+        Snippet midA = classKey(assertEval("class A { public String toString() { return \"middle\"; } }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(oldA, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertEval("a;", "middle");
+        assertEval("class A { int x; public String toString() { return \"new\"; } }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(midA, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(v, VALID, VALID, true, MAIN_SNIPPET));
+        assertEval("a;", "null");
+        assertActiveKeys();
+    }
+
+    public void testReplaceVarToMethod() {
+        Snippet x = varKey(assertEval("int x;"));
+        Snippet musn = methodKey(assertEval("double mu() { return x * 4; }"));
+        assertEval("x == 0;", "true");
+        assertEval("mu() == 0.0;", "true");
+        assertEval("double x = 2.5;",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(musn, VALID, VALID, false, MAIN_SNIPPET));
+        Collection<MethodSnippet> meths = getState().methods();
+        assertEquals(meths.size(), 1);
+        assertTrue(musn == meths.iterator().next(), "Identity must not change");
+        assertEval("x == 2.5;", "true");
+        assertEval("mu() == 10.0;", "true");  // Auto redefine
+        assertActiveKeys();
+    }
+
+    public void testReplaceMethodToMethod() {
+        Snippet a = methodKey(assertEval("double a() { return 2; }"));
+        Snippet b = methodKey(assertEval("double b() { return a() * 10; }"));
+        assertEval("double c() { return b() * 3; }");
+        assertEval("double d() { return c() + 1000; }");
+        assertEval("d();", "1060.0");
+        assertEval("int a() { return 5; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(b, VALID, VALID, false, MAIN_SNIPPET));
+        assertEval("d();", "1150.0");
+        assertActiveKeys();
+    }
+
+    public void testReplaceClassToMethod() {
+        Snippet c = classKey(assertEval("class C { int f() { return 7; } }"));
+        Snippet m = methodKey(assertEval("int m() { return new C().f(); }"));
+        assertEval("m();", "7");
+        assertEval("class C { int x = 99; int f() { return x; } }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(m, VALID, VALID, false, MAIN_SNIPPET));
+        assertEval("m();", "99");
+        assertActiveKeys();
+    }
+
+    public void testReplaceVarToClass() {
+        Snippet x = varKey(assertEval("int x;"));
+        Snippet c = classKey(assertEval("class A { double a = 4 * x; }"));
+        assertEval("x == 0;", "true");
+        assertEval("new A().a == 0.0;", "true");
+        assertEval("double x = 2.5;",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(c, VALID, VALID, false, MAIN_SNIPPET));
+        Collection<TypeDeclSnippet> classes = getState().types();
+        assertEquals(classes.size(), 1);
+        assertTrue(c == classes.iterator().next(), "Identity must not change");
+        assertEval("x == 2.5;", "true");
+        assertEval("new A().a == 10.0;", "true");
+        assertActiveKeys();
+    }
+
+    public void testReplaceMethodToClass() {
+        Snippet x = methodKey(assertEval("int x() { return 0; }"));
+        Snippet c = classKey(assertEval("class A { double a = 4 * x(); }"));
+        assertEval("x() == 0;", "true");
+        assertEval("new A().a == 0.0;", "true");
+        assertEval("double x() { return 2.5; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(c, VALID, VALID, false, MAIN_SNIPPET));
+        assertEval("x();", "2.5");
+        Collection<TypeDeclSnippet> classes = getState().types();
+        assertEquals(classes.size(), 1);
+        assertTrue(c == classes.iterator().next(), "Identity must not change");
+        assertEval("x() == 2.5;", "true");
+        assertEval("new A().a == 10.0;", "true");
+        assertActiveKeys();
+    }
+
+    public void testReplaceClassToClass() {
+        TypeDeclSnippet a = classKey(assertEval("class A {}"));
+        assertTypeDeclSnippet(a, "A", VALID, CLASS_SUBKIND, 0, 0);
+        TypeDeclSnippet b = classKey(assertEval("class B extends A {}"));
+        TypeDeclSnippet c = classKey(assertEval("class C extends B {}"));
+        TypeDeclSnippet d = classKey(assertEval("class D extends C {}"));
+        assertEval("class A { int x; public String toString() { return \"NEW\"; } }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(b, VALID, VALID, true, MAIN_SNIPPET),
+                ste(c, VALID, VALID, true, b),
+                ste(d, VALID, VALID, true, c));
+        assertTypeDeclSnippet(b, "B", VALID, CLASS_SUBKIND, 0, 0);
+        assertTypeDeclSnippet(c, "C", VALID, CLASS_SUBKIND, 0, 0);
+        assertTypeDeclSnippet(d, "D", VALID, CLASS_SUBKIND, 0, 0);
+        assertEval("new D();", "NEW");
+        assertActiveKeys();
+    }
+
+    public void testOverwriteReplaceMethod() {
+        MethodSnippet k1 = methodKey(assertEval("String m(Integer i) { return i.toString(); }"));
+        MethodSnippet k2 = methodKey(assertEval("String m(java.lang.Integer i) { return \"java.lang.\" + i.toString(); }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertMethodDeclSnippet(k1, "m", "(Integer)String", OVERWRITTEN, 0, 0);
+        assertEval("m(6);", "\"java.lang.6\"");
+        assertEval("String m(Integer i) { return i.toString(); }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(k2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertMethodDeclSnippet(k2, "m", "(java.lang.Integer)String", OVERWRITTEN, 0, 0);
+        assertEval("m(6);", "\"6\"");
+        assertActiveKeys();
+    }
+
+    public void testOverwriteMethodForwardReferenceClass() {
+        Snippet k1 = methodKey(assertEval("int q(Boo b) { return b.x; }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertUnresolvedDependencies1((MethodSnippet) k1, RECOVERABLE_NOT_DEFINED, "class Boo");
+        assertEval("class Boo { int x = 55; }",
+                added(VALID),
+                ste(k1, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertMethodDeclSnippet((MethodSnippet) k1, "q", "(Boo)int", VALID, 0, 0);
+        assertEval("q(new Boo());", "55");
+        assertActiveKeys();
+    }
+
+    public void testOverwriteMethodForwardReferenceClassImport() {
+        MethodSnippet k1 = methodKey(assertEval("int ff(List lis) { return lis.size(); }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertUnresolvedDependencies1(k1, RECOVERABLE_NOT_DEFINED, "class List");
+        assertEval("import java.util.*;",
+                added(VALID),
+                ste(k1, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertMethodDeclSnippet(k1, "ff", "(List)int", VALID, 0, 0);
+        assertEval("ff(new ArrayList());", "0");
+        assertActiveKeys();
+    }
+
+    public void testForwardVarToMethod() {
+        DeclarationSnippet t = methodKey(assertEval("int t() { return x; }", added(RECOVERABLE_DEFINED)));
+        assertUnresolvedDependencies1(t, RECOVERABLE_DEFINED, "variable x");
+        assertEvalUnresolvedException("t();", "t", 1, 0);
+        Snippet x = varKey(assertEval("int x = 33;", "33",
+                added(VALID),
+                ste(t, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertEval("t();", "33");
+        assertEval("double x = 0.88;",
+                "0.88", null,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(t, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET));
+        assertEvalUnresolvedException("t();", "t", 0, 1);
+        assertActiveKeys();
+    }
+
+    public void testForwardMethodToMethod() {
+        Snippet t = methodKey(assertEval("int t() { return f(); }", added(RECOVERABLE_DEFINED)));
+        Snippet f = methodKey(assertEval("int f() { return g(); }",
+                added(RECOVERABLE_DEFINED),
+                ste(t, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertUnresolvedDependencies1((DeclarationSnippet) f, RECOVERABLE_DEFINED, "method g()");
+        assertEvalUnresolvedException("t();", "f", 1, 0);
+        Snippet g = methodKey(assertEval("int g() { return 55; }",
+                added(VALID),
+                ste(f, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertEval("t();", "55");
+        assertEval("double g() { return 3.14159; }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(f, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET));
+        MethodSnippet exsn = assertEvalUnresolvedException("t();", "f", 0, 1);
+        assertTrue(exsn == f, "Identity must not change");
+        assertActiveKeys();
+    }
+
+    public void testForwardClassToMethod() {
+        DeclarationSnippet t = methodKey(assertEval("int t() { return new A().f(); }", added(RECOVERABLE_DEFINED)));
+        assertUnresolvedDependencies1(t, RECOVERABLE_DEFINED, "class A");
+        assertEvalUnresolvedException("t();", "t", 1, 0);
+        Snippet a = classKey(assertEval(
+                "class A {\n" +
+                        "   int f() { return 10; }\n" +
+                "}",
+                added(VALID),
+                ste(t, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertEval("t();", "10");
+        assertEval(
+                "class A {\n" +
+                "   double f() { return 88.0; }\n" +
+                "}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(t, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET));
+        assertEvalUnresolvedException("t();", "t", 0, 1);
+        assertActiveKeys();
+    }
+
+    public void testForwardVarToClass() {
+        DeclarationSnippet a = classKey(assertEval("class A { int f() { return g; } }", added(RECOVERABLE_NOT_DEFINED)));
+        assertUnresolvedDependencies1(a, RECOVERABLE_NOT_DEFINED, "variable g");
+        Snippet g = varKey(assertEval("int g = 10;", "10",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)));
+        assertEval("new A().f();", "10");
+        assertEval("double g = 10;", "10.0", null,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertUnresolvedDependencies(a, 0);
+        assertActiveKeys();
+    }
+
+
+    public void testForwardMethodToClass() {
+        DeclarationSnippet a = classKey(assertEval("class A { int f() { return g(); } }", added(RECOVERABLE_NOT_DEFINED)));
+        assertUnresolvedDependencies1(a, RECOVERABLE_NOT_DEFINED, "method g()");
+        Snippet g = methodKey(assertEval("int g() { return 10; }",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)));
+        assertEval("new A().f();", "10");
+        assertEval("double g() { return 10; }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(g, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertUnresolvedDependencies(a, 0);
+        assertActiveKeys();
+    }
+
+    public void testForwardClassToClass1() {
+        Snippet a = classKey(assertEval("class A { B b = new B(); }", added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A().b;", "compiler.err.cant.resolve.location");
+
+        Snippet b = classKey(assertEval("class B { public String toString() { return \"B\"; } }",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)));
+        assertEval("new A().b;", "B");
+        assertEval("interface B { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertDeclareFail("new A().b;", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+    }
+
+    public void testForwardClassToClass2() {
+        Snippet a = classKey(assertEval("class A extends B { }", added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+
+        Snippet b = classKey(assertEval("class B { public String toString() { return \"B\"; } }",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)));
+        assertEval("new A();", "B");
+        assertEval("interface B { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+    }
+
+    public void testForwardClassToClass3() {
+        Snippet a = classKey(assertEval("interface A extends B { static int f() { return 10; } }", added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("A.f();", "compiler.err.cant.resolve.location");
+
+        Snippet b = classKey(assertEval("interface B { }",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null)));
+        assertEval("A.f();", "10");
+        assertEval("class B { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertDeclareFail("A.f();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+    }
+
+    public void testImportDeclare() {
+        Snippet singleImport = importKey(assertEval("import java.util.List;", added(VALID)));
+        Snippet importOnDemand = importKey(assertEval("import java.util.*;", added(VALID)));
+        Snippet singleStaticImport = importKey(assertEval("import static java.lang.Math.abs;", added(VALID)));
+        Snippet staticImportOnDemand = importKey(assertEval("import static java.lang.Math.*;", added(VALID)));
+        assertEval("import java.util.List; //again",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(singleImport, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("import java.util.*; //again",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(importOnDemand, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("import static java.lang.Math.abs; //again",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(singleStaticImport, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertEval("import static java.lang.Math.*; //again",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(staticImportOnDemand, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertActiveKeys();
+    }
+
+    public void testForwardVariable() {
+        assertEval("int f() { return x; }", added(RECOVERABLE_DEFINED));
+        assertEvalUnresolvedException("f();", "f", 1, 0);
+        assertActiveKeys();
+    }
+
+    public void testLocalClassInUnresolved() {
+        Snippet f = methodKey(assertEval("void f() { class A {} g(); }", added(RECOVERABLE_DEFINED)));
+        assertEval("void g() {}",
+                added(VALID),
+                ste(f, RECOVERABLE_DEFINED, VALID, false, null));
+        assertEval("f();", "");
+    }
+
+    @Test(enabled = false) // TODO 8129420
+    public void testLocalClassEvolve() {
+        Snippet j = methodKey(assertEval("Object j() { return null; }", added(VALID)));
+        assertEval("Object j() { class B {}; return null; }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null));
+        assertEval("Object j() { class B {}; return new B(); }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null));
+        assertEval("j().getClass().getSimpleName();", "\"B\"");
+        assertEval("Object j() { class B { int p; public String toString() { return \"Yep\";} }; return new B(); }",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null));
+        assertEval("j().getClass().getSimpleName();", "\"B\"");
+        assertEval("j();", "Yep");
+    }
+
+    public void testForwardSingleImportMethodToMethod() {
+        DeclarationSnippet string = methodKey(assertEval("String string() { return format(\"string\"); }",
+                added(RECOVERABLE_DEFINED)));
+        assertUnresolvedDependencies1(string, RECOVERABLE_DEFINED, "method format(java.lang.String)");
+        assertEvalUnresolvedException("string();", "string", 1, 0);
+        assertEval("import static java.lang.String.format;",
+                added(VALID),
+                ste(string, RECOVERABLE_DEFINED, VALID, false, null));
+        assertEval("string();", "\"string\"");
+
+        assertEval("double format(String s) { return 0; }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(string, VALID, RECOVERABLE_DEFINED, false, null));
+        assertEvalUnresolvedException("string();", "string", 0, 1);
+        assertActiveKeys();
+    }
+
+    public void testForwardImportMethodOnDemandToMethod() {
+        DeclarationSnippet string = methodKey(assertEval("String string() { return format(\"string\"); }",
+                added(RECOVERABLE_DEFINED)));
+        assertUnresolvedDependencies1(string, RECOVERABLE_DEFINED, "method format(java.lang.String)");
+        assertEvalUnresolvedException("string();", "string", 1, 0);
+        assertEval("import static java.lang.String.*;",
+                added(VALID),
+                ste(string, RECOVERABLE_DEFINED, VALID, false, null));
+        assertEval("string();", "\"string\"");
+
+        assertEval("double format(String s) { return 0; }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(string, VALID, RECOVERABLE_DEFINED, false, null));
+        assertEvalUnresolvedException("string();", "string", 0, 1);
+        assertActiveKeys();
+    }
+
+    public void testForwardSingleImportFieldToMethod() {
+        DeclarationSnippet pi = methodKey(assertEval("double pi() { return PI; }",
+                added(RECOVERABLE_DEFINED)));
+        assertUnresolvedDependencies1(pi, RECOVERABLE_DEFINED, "variable PI");
+        assertEvalUnresolvedException("pi();", "pi", 1, 0);
+        assertEval("import static java.lang.Math.PI;",
+                added(VALID),
+                ste(pi, RECOVERABLE_DEFINED, VALID, false, null));
+        assertEval("Math.abs(pi() - 3.1415) < 0.001;", "true");
+
+        assertEval("String PI;",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(pi, VALID, RECOVERABLE_DEFINED, false, null));
+        assertEvalUnresolvedException("pi();", "pi", 0, 1);
+        assertActiveKeys();
+    }
+
+    public void testForwardImportFieldOnDemandToMethod() {
+        DeclarationSnippet pi = methodKey(assertEval("double pi() { return PI; }",
+                added(RECOVERABLE_DEFINED)));
+        assertUnresolvedDependencies1(pi, RECOVERABLE_DEFINED, "variable PI");
+        assertEvalUnresolvedException("pi();", "pi", 1, 0);
+        assertEval("import static java.lang.Math.*;",
+                added(VALID),
+                ste(pi, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
+        assertEval("Math.abs(pi() - 3.1415) < 0.001;", "true");
+
+        assertEval("String PI;",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(pi, VALID, RECOVERABLE_DEFINED, false, MAIN_SNIPPET));
+        assertEvalUnresolvedException("pi();", "pi", 0, 1);
+        assertActiveKeys();
+    }
+
+    public void testForwardSingleImportMethodToClass1() {
+        PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.String.format;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("new A().s;", "\"10\"");
+        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET)));
+        assertDeclareFail("new A().s;", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(format,
+                ste(format, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, format));
+    }
+
+    public void testForwardSingleImportMethodToClass2() {
+        PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.String.format;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("new A().s();", "\"10\"");
+        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A().s();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(format,
+                ste(format, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, format));
+    }
+
+    public void testForwardSingleImportClassToClass1() {
+        PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import java.util.List;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("import java.util.Arrays;", added(VALID));
+        assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
+
+        PersistentSnippet list = classKey(assertEval("class List {}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("A.list = Arrays.asList(1, 2, 3);", "compiler.err.already.defined.static.single.import");
+        assertActiveKeys();
+        assertDrop(list,
+                ste(list, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list));
+    }
+
+    public void testForwardSingleImportClassToClass2() {
+        PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import java.util.ArrayList;",
+                added(VALID),
+                ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
+        Snippet vara = varKey(assertEval("A a = new A();", "[]"));
+
+        PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(clsA, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET),
+                ste(vara, VALID, RECOVERABLE_NOT_DEFINED, true, clsA)));
+        assertDeclareFail("A a = new A();", "compiler.err.cant.resolve.location",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, REJECTED, false, null),
+                ste(vara, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertActiveKeys();
+        assertDrop(arraylist,
+                ste(arraylist, VALID, DROPPED, true, null),
+                ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, arraylist));
+    }
+
+    public void testForwardImportOnDemandMethodToClass1() {
+        PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.String.*;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("new A().s;", "\"10\"");
+        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A().s;", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(format,
+                ste(format, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, format));
+    }
+
+    public void testForwardImportOnDemandMethodToClass2() {
+        PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.String.*;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("new A().s();", "\"10\"");
+        PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A().s();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(format,
+                ste(format, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, format));
+    }
+
+    public void testForwardImportOnDemandClassToClass1() {
+        PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import java.util.*;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
+
+        PersistentSnippet list = classKey(assertEval("class List {}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("A.list = Arrays.asList(1, 2, 3);", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(list,
+                ste(list, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list));
+    }
+
+    public void testForwardImportOnDemandClassToClass2() {
+        PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import java.util.*;",
+                added(VALID),
+                ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
+        Snippet vara = varKey(assertEval("A a = new A();", "[]"));
+
+        PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(clsA, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET),
+                ste(vara, VALID, RECOVERABLE_NOT_DEFINED, true, clsA)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(arraylist,
+                ste(arraylist, VALID, DROPPED, true, null),
+                ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, arraylist),
+                ste(vara, RECOVERABLE_NOT_DEFINED, VALID, true, clsA));
+    }
+
+    public void testForwardSingleImportFieldToClass1() {
+        PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.Math.PI;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
+
+        PersistentSnippet list = varKey(assertEval("String PI;",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(list,
+                ste(list, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list));
+    }
+
+    public void testForwardSingleImportFieldToClass2() {
+        PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.Math.PI;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
+
+        PersistentSnippet list = varKey(assertEval("String PI;",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(list,
+                ste(list, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list));
+    }
+
+    public void testForwardImportOnDemandFieldToClass1() {
+        PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.Math.*;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
+
+        PersistentSnippet list = varKey(assertEval("String PI;",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(list,
+                ste(list, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list));
+    }
+
+    public void testForwardImportOnDemandFieldToClass2() {
+        PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+                added(RECOVERABLE_NOT_DEFINED)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertEval("import static java.lang.Math.*;",
+                added(VALID),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
+        assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
+
+        PersistentSnippet list = varKey(assertEval("String PI;",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(a, VALID, RECOVERABLE_NOT_DEFINED, true, null)));
+        assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
+        assertActiveKeys();
+        assertDrop(list,
+                ste(list, VALID, DROPPED, true, null),
+                ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, list));
+    }
+
+    public void testReplaceCausesMethodReferenceError() {
+        Snippet l = classKey(assertEval("interface Logger { public void log(String message); }", added(VALID)));
+        Snippet v = varKey(assertEval("Logger l = System.out::println;", added(VALID)));
+        assertEval("interface Logger { public boolean accept(String message);  }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(l, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(v, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+    }
+
+    public void testReplaceCausesClassCompilationError() {
+        Snippet l = classKey(assertEval("interface L { }", added(VALID)));
+        Snippet c = classKey(assertEval("class C implements L { }", added(VALID)));
+        assertEval("interface L { void m(); }",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(l, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(c, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+    }
+
+    public void testOverwriteNoUpdate() {
+        String xsi = "int x = 5;";
+        String xsd = "double x = 3.14159;";
+        VarSnippet xi = varKey(assertEval(xsi, added(VALID)));
+        String ms1 = "double m(Integer i) { return i + x; }";
+        String ms2 = "double m(java.lang.Integer i) { return i + x; }";
+        MethodSnippet k1 = methodKey(assertEval(ms1, added(VALID)));
+        VarSnippet xd = varKey(assertEval(xsd,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(xi, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(k1, VALID, VALID, false, MAIN_SNIPPET)));
+        MethodSnippet k2 = methodKey(assertEval(ms2,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null), //TODO: technically, should be false
+                ste(k1, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        VarSnippet xi2 = varKey(assertEval(xsi,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(xd, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
+        varKey(assertEval(xsd,
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(xi2, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(k2, VALID, VALID, false, MAIN_SNIPPET)));
+    }
+}
diff --git a/langtools/test/jdk/jshell/ShutdownTest.java b/langtools/test/jdk/jshell/ShutdownTest.java
new file mode 100644
index 0000000..45431f6
--- /dev/null
+++ b/langtools/test/jdk/jshell/ShutdownTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Shutdown tests
+ * @build KullaTesting TestingInputStream
+ * @run testng ShutdownTest
+ */
+
+import java.util.function.Consumer;
+
+import jdk.jshell.JShell;
+import jdk.jshell.JShell.Subscription;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class ShutdownTest extends KullaTesting {
+
+    int shutdownCount;
+
+    void shutdownCounter(JShell state) {
+        ++shutdownCount;
+    }
+
+    @Test(enabled = false) //TODO 8139873
+    public void testExit() {
+        shutdownCount = 0;
+        getState().onShutdown(this::shutdownCounter);
+        assertEval("System.exit(1);");
+        assertEquals(shutdownCount, 1);
+    }
+
+    public void testCloseCallback() {
+        shutdownCount = 0;
+        getState().onShutdown(this::shutdownCounter);
+        getState().close();
+        assertEquals(shutdownCount, 1);
+    }
+
+    public void testCloseUnsubscribe() {
+        shutdownCount = 0;
+        Subscription token = getState().onShutdown(this::shutdownCounter);
+        getState().unsubscribe(token);
+        getState().close();
+        assertEquals(shutdownCount, 0);
+    }
+
+    public void testTwoShutdownListeners() {
+        ShutdownListener listener1 = new ShutdownListener();
+        ShutdownListener listener2 = new ShutdownListener();
+        Subscription subscription1 = getState().onShutdown(listener1);
+        Subscription subscription2 = getState().onShutdown(listener2);
+        getState().unsubscribe(subscription1);
+        getState().close();
+
+        assertEquals(listener1.getEvents(), 0, "Checking got events");
+        assertEquals(listener2.getEvents(), 1, "Checking got events");
+
+        getState().close();
+
+        assertEquals(listener1.getEvents(), 0, "Checking got events");
+        assertEquals(listener2.getEvents(), 1, "Checking got events");
+
+        getState().unsubscribe(subscription2);
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testCloseException() {
+        getState().close();
+        getState().eval("45");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class,
+          enabled = false) //TODO 8139873
+    public void testShutdownException() {
+        assertEval("System.exit(0);");
+        getState().eval("45");
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNullCallback() {
+        getState().onShutdown(null);
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testSubscriptionAfterClose() {
+        getState().close();
+        getState().onShutdown(e -> {});
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class,
+          enabled = false) //TODO 8139873
+    public void testSubscriptionAfterShutdown() {
+        assertEval("System.exit(0);");
+        getState().onShutdown(e -> {});
+    }
+
+    private static class ShutdownListener implements Consumer<JShell> {
+        private int count;
+
+        @Override
+        public void accept(JShell shell) {
+            ++count;
+        }
+
+        public int getEvents() {
+            return count;
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/SimpleRegressionTest.java b/langtools/test/jdk/jshell/SimpleRegressionTest.java
new file mode 100644
index 0000000..1ded002
--- /dev/null
+++ b/langtools/test/jdk/jshell/SimpleRegressionTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 simple regression test
+ * @build KullaTesting TestingInputStream
+ * @run testng SimpleRegressionTest
+ */
+
+
+import java.util.List;
+
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Snippet;
+import jdk.jshell.VarSnippet;
+import jdk.jshell.SnippetEvent;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static jdk.jshell.Snippet.SubKind.TEMP_VAR_EXPRESSION_SUBKIND;
+import static jdk.jshell.Snippet.Status.VALID;
+
+@Test
+public class SimpleRegressionTest extends KullaTesting {
+
+    public void testSnippetMemberAssignment() {
+        assertEval("class C { int y; }");
+        assertEval("C c = new C();");
+        assertVarKeyMatch("c.y = 4;", true, "$1", TEMP_VAR_EXPRESSION_SUBKIND, "int", added(VALID));
+    }
+
+    public void testUserTakesTempVarName() {
+        assertEval("int $2 = 4;");
+        assertEval("String $1;");
+        assertVarKeyMatch("1234;", true, "$3", TEMP_VAR_EXPRESSION_SUBKIND, "int", added(VALID));
+    }
+
+    public void testCompileThrow() {
+        assertEvalException("throw new Exception();");
+    }
+
+    public void testMultiSnippetDependencies() {
+        List<SnippetEvent> events = assertEval("int a = 3, b = a+a, c = b *100;",
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_OK,
+                chain(added(VALID)),
+                chain(added(VALID)),
+                chain(added(VALID)));
+        assertEquals(events.get(0).value(), "3");
+        assertEquals(events.get(1).value(), "6");
+        assertEquals(events.get(2).value(), "600");
+        assertEval("c;", "600");
+    }
+
+    public void testNotStmtCannotResolve() {
+        assertDeclareFail("dfasder;", new ExpectedDiagnostic("compiler.err.cant.resolve.location", 0, 7, 0, -1, -1, Diagnostic.Kind.ERROR));
+    }
+
+    public void testNotStmtIncomparable() {
+        assertDeclareFail("true == 5.0;", new ExpectedDiagnostic("compiler.err.incomparable.types", 0, 11, 5, -1, -1, Diagnostic.Kind.ERROR));
+    }
+
+    public void testStringAdd() {
+        assertEval("String s = \"a\" + \"b\";", "\"ab\"");
+    }
+
+    public void testExprSanity() {
+        assertEval("int x = 3;", "3");
+        assertEval("int y = 4;", "4");
+        assertEval("x + y;", "7");
+        assertActiveKeys();
+    }
+
+    public void testGenericMethodCrash() {
+        assertDeclareWarn1("<T> void f(T...a) {}", (ExpectedDiagnostic) null);
+        Snippet sn = methodKey(assertEval("<R> R n(R x) { return x; }", added(VALID)));
+        VarSnippet sne = varKey(assertEval("n(5)", added(VALID)));
+        assertEquals(sne.typeName(), "Integer");
+    }
+}
diff --git a/langtools/test/jdk/jshell/SnippetStatusListenerTest.java b/langtools/test/jdk/jshell/SnippetStatusListenerTest.java
new file mode 100644
index 0000000..715b350
--- /dev/null
+++ b/langtools/test/jdk/jshell/SnippetStatusListenerTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Subscribe tests
+ * @build KullaTesting TestingInputStream
+ * @run testng SnippetStatusListenerTest
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+
+import jdk.jshell.DeclarationSnippet;
+import jdk.jshell.JShell.Subscription;
+import jdk.jshell.SnippetEvent;
+import jdk.jshell.TypeDeclSnippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.*;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class SnippetStatusListenerTest extends KullaTesting {
+
+    public void testTwoSnippetEventListeners() {
+        SnippetListener listener1 = new SnippetListener();
+        SnippetListener listener2 = new SnippetListener();
+
+        Subscription subscription1 = getState().onSnippetEvent(listener1);
+        getState().onSnippetEvent(listener2);
+
+        TypeDeclSnippet a = classKey(assertEval("class A {}"));
+        assertEval("interface A {}",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, null));
+        DeclarationSnippet f = (DeclarationSnippet) assertDeclareFail("double f() { }", "compiler.err.missing.ret.stmt");
+        assertEvalException("throw new RuntimeException();");
+        assertEval("int a = 0;");
+
+        List<SnippetEvent> events1 = Collections.unmodifiableList(listener1.getEvents());
+        assertEquals(events1, listener2.getEvents(), "Checking got events");
+        getState().unsubscribe(subscription1);
+
+        assertDrop(f, DiagCheck.DIAG_IGNORE, DiagCheck.DIAG_IGNORE, ste(f, REJECTED, DROPPED, false, null));
+        assertEval("void f() { }", ste(MAIN_SNIPPET, DROPPED, VALID, true, null));
+        assertEvalException("throw new RuntimeException();");
+        assertEquals(listener1.getEvents(), events1, "Checking that unsubscribed listener does not get events");
+
+        List<SnippetEvent> events2 = new ArrayList<>(listener2.getEvents());
+        events2.removeAll(events1);
+
+        assertEquals(events2.size(), 3, "The second listener got events");
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNullCallback() {
+        getState().onSnippetEvent(null);
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testSubscriptionAfterClose() {
+        getState().close();
+        getState().onSnippetEvent(e -> {});
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class,
+          enabled = false) //TODO 8139873
+    public void testSubscriptionAfterShutdown() {
+        assertEval("System.exit(0);");
+        getState().onSnippetEvent(e -> {});
+    }
+
+    public void testSubscriptionToAnotherState() {
+        SnippetListener listener = new SnippetListener();
+        Subscription subscription = getState().onSnippetEvent(listener);
+        tearDown();
+        setUp();
+        assertEval("int x;");
+        assertEquals(Collections.emptyList(), listener.getEvents(), "No events");
+        getState().unsubscribe(subscription);
+    }
+
+    private static class SnippetListener implements Consumer<SnippetEvent> {
+        private final List<SnippetEvent> events = new ArrayList<>();
+
+        @Override
+        public void accept(SnippetEvent event) {
+            events.add(event);
+        }
+
+        public List<SnippetEvent> getEvents() {
+            return events;
+        }
+    }
+}
diff --git a/langtools/test/jdk/jshell/SnippetTest.java b/langtools/test/jdk/jshell/SnippetTest.java
new file mode 100644
index 0000000..e3176c0
--- /dev/null
+++ b/langtools/test/jdk/jshell/SnippetTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 accessors of Snippet
+ * @build KullaTesting TestingInputStream
+ * @run testng SnippetTest
+ */
+
+import jdk.jshell.Snippet;
+import jdk.jshell.DeclarationSnippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
+import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+import static jdk.jshell.Snippet.SubKind.*;
+
+@Test
+public class SnippetTest extends KullaTesting {
+
+    public void testImportKey() {
+        assertImportKeyMatch("import java.util.List;", "List", SINGLE_TYPE_IMPORT_SUBKIND, added(VALID));
+        assertImportKeyMatch("import java.util.*;", "java.util.*", TYPE_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
+        assertImportKeyMatch("import static java.lang.String.*;", "java.lang.String.*", STATIC_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
+    }
+
+    public void testClassKey() {
+        assertDeclarationKeyMatch("class X {}", false, "X", CLASS_SUBKIND, added(VALID));
+    }
+
+    public void testInterfaceKey() {
+        assertDeclarationKeyMatch("interface I {}", false, "I", INTERFACE_SUBKIND, added(VALID));
+    }
+
+    public void testEnumKey() {
+        assertDeclarationKeyMatch("enum E {}", false, "E", ENUM_SUBKIND, added(VALID));
+    }
+
+    public void testAnnotationKey() {
+        assertDeclarationKeyMatch("@interface A {}", false, "A", ANNOTATION_TYPE_SUBKIND, added(VALID));
+    }
+
+    public void testMethodKey() {
+        assertDeclarationKeyMatch("void m() {}", false, "m", METHOD_SUBKIND, added(VALID));
+    }
+
+    public void testVarDeclarationKey() {
+        assertVarKeyMatch("int a;", false, "a", VAR_DECLARATION_SUBKIND, "int", added(VALID));
+    }
+
+    public void testVarDeclarationWithInitializerKey() {
+        assertVarKeyMatch("double b = 9.0;", true, "b", VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, "double", added(VALID));
+    }
+
+    public void testTempVarExpressionKey() {
+        assertVarKeyMatch("47;", true, "$1", TEMP_VAR_EXPRESSION_SUBKIND, "int", added(VALID));
+    }
+
+    public void testVarValueKey() {
+        assertEval("double x = 4;", "4.0");
+        assertExpressionKeyMatch("x;", "x", VAR_VALUE_SUBKIND, "double");
+    }
+
+    public void testAssignmentKey() {
+        assertEval("int y;");
+        assertExpressionKeyMatch("y = 4;", "y", ASSIGNMENT_SUBKIND, "int");
+    }
+
+    public void testStatementKey() {
+        assertKeyMatch("if (true) {}", true, STATEMENT_SUBKIND, added(VALID));
+        assertKeyMatch("while (true) { break; }", true, STATEMENT_SUBKIND, added(VALID));
+        assertKeyMatch("do { } while (false);", true, STATEMENT_SUBKIND, added(VALID));
+        assertKeyMatch("for (;;) { break; }", true, STATEMENT_SUBKIND, added(VALID));
+    }
+
+    public void noKeys() {
+        assertActiveKeys(new DeclarationSnippet[0]);
+    }
+
+    public void testKeyId1() {
+        Snippet a = classKey(assertEval("class A { }"));
+        assertEval("void f() {  }");
+        assertEval("int f;");
+        assertEval("interface A { }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertKeys(method("()void", "f"), variable("int", "f"), clazz(KullaTesting.ClassType.INTERFACE, "A"));
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081689
+    public void testKeyId2() {
+        Snippet g = methodKey(assertEval("void g() { f(); }", added(RECOVERABLE_DEFINED)));
+        Snippet f = methodKey(assertEval("void f() { }",
+                added(VALID),
+                ste(g, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertEval("int f;");
+        assertEval("interface A { }");
+        assertKeys(method("()void", "g"), method("()void", "f"), variable("int", "f"),
+                clazz(KullaTesting.ClassType.INTERFACE, "A"));
+        assertActiveKeys();
+        assertEval("double f() { return 0.0; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(g, VALID, VALID, false, MAIN_SNIPPET));
+        assertKeys(method("()void", "g"), method("()double", "f"), variable("int", "f"),
+                clazz(KullaTesting.ClassType.INTERFACE, "A"));
+        assertActiveKeys();
+    }
+
+    public void testKeyId3() {
+        Snippet g = methodKey(assertEval("void g() { f(); }", added(RECOVERABLE_DEFINED)));
+        Snippet f = methodKey(assertEval("void f() { }",
+                added(VALID),
+                ste(g, RECOVERABLE_DEFINED, VALID, false, null)));
+        assertDeclareFail("qqqq;", "compiler.err.cant.resolve.location");
+        assertEval("interface A { }");
+        assertKeys(method("()void", "g"), method("()void", "f"),
+                clazz(KullaTesting.ClassType.INTERFACE, "A"));
+        assertActiveKeys();
+        assertEval("double f() { return 0.0; }",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(f, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
+                ste(g, VALID, VALID, false, MAIN_SNIPPET));
+        assertKeys(method("()void", "g"), clazz(KullaTesting.ClassType.INTERFACE, "A"),
+                method("()double", "f"));
+        assertActiveKeys();
+    }
+}
diff --git a/langtools/test/jdk/jshell/StartOptionTest.java b/langtools/test/jdk/jshell/StartOptionTest.java
new file mode 100644
index 0000000..ff5d4de
--- /dev/null
+++ b/langtools/test/jdk/jshell/StartOptionTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Testing start-up options.
+ * @library /tools/lib
+ * @build Compiler ToolBox
+ * @run testng StartOptionTest
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.function.Consumer;
+
+import jdk.internal.jshell.tool.JShellTool;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class StartOptionTest {
+
+    private ByteArrayOutputStream out;
+    private ByteArrayOutputStream err;
+
+    private JShellTool getShellTool() {
+        return new JShellTool(null, new PrintStream(out), new PrintStream(err), null, null, null, null);
+    }
+
+    private String getOutput() {
+        byte[] bytes = out.toByteArray();
+        out.reset();
+        return new String(bytes, StandardCharsets.UTF_8);
+    }
+
+    private String getError() {
+        byte[] bytes = err.toByteArray();
+        err.reset();
+        return new String(bytes, StandardCharsets.UTF_8);
+    }
+
+    private void start(Consumer<String> checkOutput, Consumer<String> checkError, String... args) throws Exception {
+        JShellTool tool = getShellTool();
+        tool.start(args);
+        if (checkOutput != null) {
+            checkOutput.accept(getOutput());
+        } else {
+            assertEquals("", getOutput(), "Output: ");
+        }
+        if (checkError != null) {
+            checkError.accept(getError());
+        } else {
+            assertEquals("", getError(), "Error: ");
+        }
+    }
+
+    private void start(String expectedOutput, String expectedError, String... args) throws Exception {
+        start(s -> assertEquals(s, expectedOutput, "Output: "), s -> assertEquals(s, expectedError, "Error: "), args);
+    }
+
+    @BeforeMethod
+    public void setUp() {
+        out = new ByteArrayOutputStream();
+        err = new ByteArrayOutputStream();
+    }
+
+    @Test
+    public void testUsage() throws Exception {
+        start(s -> {
+            assertTrue(s.split("\n").length >= 7, s);
+            assertTrue(s.startsWith("Usage:   jshell <options>"), s);
+        },  null, "-help");
+    }
+
+    @Test
+    public void testUnknown() throws Exception {
+        start(s -> {
+            assertTrue(s.split("\n").length >= 7, s);
+            assertTrue(s.startsWith("Usage:   jshell <options>"), s);
+        }, s -> assertEquals(s, "Unknown option: -unknown\n"), "-unknown");
+    }
+
+    @Test(enabled = false) // TODO 8080883
+    public void testStartup() throws Exception {
+        Compiler compiler = new Compiler();
+        Path p = compiler.getPath("file.txt");
+        compiler.writeToFile(p);
+        start("", "Argument to -startup missing.\n", "-startup");
+        start("", "Conflicting -startup or -nostartup option.\n", "-startup", p.toString(), "-startup", p.toString());
+        start("", "Conflicting -startup or -nostartup option.\n", "-nostartup", "-startup", p.toString());
+        start("", "Conflicting -startup option.\n", "-startup", p.toString(), "-nostartup");
+    }
+
+    @Test
+    public void testClasspath() throws Exception {
+        for (String cp : new String[] {"-cp", "-classpath"}) {
+            start("", "Conflicting -classpath option.\n", cp, ".", "-classpath", ".");
+            start("", "Argument to -classpath missing.\n", cp);
+        }
+    }
+
+    @Test
+    public void testVersion() throws Exception {
+        start(s -> assertTrue(s.startsWith("jshell")), null, "-version");
+    }
+
+    @AfterMethod
+    public void tearDown() {
+        out = null;
+        err = null;
+    }
+}
diff --git a/langtools/test/jdk/jshell/StopExecutionTest.java b/langtools/test/jdk/jshell/StopExecutionTest.java
new file mode 100644
index 0000000..4c2af11
--- /dev/null
+++ b/langtools/test/jdk/jshell/StopExecutionTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 JShell#stop
+ * @build KullaTesting TestingInputStream
+ * @run testng StopExecutionTest
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Random;
+
+import jdk.internal.jshell.tool.StopDetectingInputStream;
+import jdk.internal.jshell.tool.StopDetectingInputStream.State;
+import jdk.jshell.JShell;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+@Test
+public class StopExecutionTest extends KullaTesting {
+
+    private final Object lock = new Object();
+    private boolean isStopped;
+
+    @Test(enabled = false) // TODO 8129546
+    public void testStopLoop() throws InterruptedException {
+        scheduleStop("while (true) ;");
+    }
+
+    @Test(enabled = false) // TODO 8129546
+    public void testStopASleep() throws InterruptedException {
+        scheduleStop("while (true) { try { Thread.sleep(100); } catch (InterruptedException ex) { } }");
+    }
+
+    @Test(enabled = false) // TODO 8129546
+    public void testScriptCatchesStop() throws Exception {
+        scheduleStop("for (int i = 0; i < 30; i++) { try { Thread.sleep(100); } catch (Throwable ex) { } }");
+    }
+
+    private void scheduleStop(String src) throws InterruptedException {
+        JShell state = getState();
+        isStopped = false;
+        StringWriter writer = new StringWriter();
+        PrintWriter out = new PrintWriter(writer);
+        Thread t = new Thread(() -> {
+            int i = 1;
+            int n = 30;
+            synchronized (lock) {
+                do {
+                    state.stop();
+                    if (!isStopped) {
+                        out.println("Not stopped. Try again: " + i);
+                        try {
+                            lock.wait(1000);
+                        } catch (InterruptedException ignored) {
+                        }
+                    }
+                } while (i++ < n && !isStopped);
+                if (!isStopped) {
+                    System.err.println(writer.toString());
+                    fail("Evaluation was not stopped: '" + src + "'");
+                }
+            }
+        });
+        t.start();
+        assertEval(src);
+        synchronized (lock) {
+            out.println("Evaluation was stopped successfully: '" + src + "'");
+            isStopped = true;
+            lock.notify();
+        }
+        // wait until the background thread finishes to prevent from calling 'stop' on closed state.
+        t.join();
+    }
+
+    public void testStopDetectingInputRandom() throws IOException {
+        long seed = System.nanoTime();
+        Random r = new Random(seed);
+
+        for (int m = 0; m < 10; m++) {
+            StopDetectingInputStream buffer = new StopDetectingInputStream(null, null);
+
+            buffer.setState(State.BUFFER);
+
+            for (int i = 0; i < 1000; i++) {
+                int chunkSize = r.nextInt(StopDetectingInputStream.INITIAL_SIZE * 3);
+
+                doChunk(buffer, chunkSize);
+            }
+        }
+    }
+
+    private void doChunk(StopDetectingInputStream buffer, int chunkSize) throws IOException {
+        for (int c = 0; c < chunkSize; c++) {
+            buffer.write(c);
+        }
+
+        for (int c = 0; c < chunkSize; c++) {
+            int read = buffer.read();
+
+            assertEquals(read, c);
+        }
+    }
+
+}
diff --git a/langtools/test/jdk/jshell/TestingInputStream.java b/langtools/test/jdk/jshell/TestingInputStream.java
new file mode 100644
index 0000000..f9d3708
--- /dev/null
+++ b/langtools/test/jdk/jshell/TestingInputStream.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+
+class TestingInputStream extends ByteArrayInputStream {
+
+    TestingInputStream() {
+        super(new byte[0]);
+    }
+
+    void setInput(String s) {
+        this.buf = s.getBytes();
+        this.pos = 0;
+        this.count = buf.length;
+    }
+
+}
diff --git a/langtools/test/jdk/jshell/ToolBasicTest.java b/langtools/test/jdk/jshell/ToolBasicTest.java
new file mode 100644
index 0000000..d9137ce
--- /dev/null
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java
@@ -0,0 +1,846 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for Basic tests for REPL tool
+ * @ignore 8139873
+ * @library /tools/lib
+ * @build KullaTesting TestingInputStream ToolBox Compiler
+ * @run testng ToolBasicTest
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+import java.util.function.Consumer;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test
+public class ToolBasicTest extends ReplToolTesting {
+
+    public void defineVar() {
+        test(
+                (a) -> assertCommand(a, "int x = 72", "|  Added variable x of type int with initial value 72\n"),
+                (a) -> assertCommand(a, "x", "|  Variable x of type int has value 72\n"),
+                (a) -> assertCommand(a, "/vars", "|    int x = 72\n")
+        );
+    }
+
+    public void defineUnresolvedVar() {
+        test(
+                (a) -> assertCommand(a, "undefined x",
+                        "|  Added variable x, however, it cannot be referenced until class undefined is declared\n"),
+                (a) -> assertCommand(a, "/vars", "|    undefined x = (not-active)\n")
+        );
+    }
+
+    public void testUnresolved() {
+        test(
+                (a) -> assertCommand(a, "int f() { return g() + x + new A().a; }",
+                        "|  Added method f(), however, it cannot be invoked until method g(), variable x, and class A are declared\n"),
+                (a) -> assertCommand(a, "f()",
+                        "|  Attempted to call f which cannot be invoked until method g(), variable x, and class A are declared\n"),
+                (a) -> assertCommand(a, "int g() { return x; }",
+                        "|  Added method g(), however, it cannot be invoked until variable x is declared\n"),
+                (a) -> assertCommand(a, "g()", "|  Attempted to call g which cannot be invoked until variable x is declared\n")
+        );
+    }
+
+    public void elideStartUpFromList() {
+        test(
+                (a) -> assertCommandCheckOutput(a, "123", (s) ->
+                        assertTrue(s.contains("type int"), s)),
+                (a) -> assertCommandCheckOutput(a, "/list", (s) -> {
+                    int cnt;
+                    try (Scanner scanner = new Scanner(s)) {
+                        cnt = 0;
+                        while (scanner.hasNextLine()) {
+                            String line = scanner.nextLine();
+                            if (!line.trim().isEmpty()) {
+                                ++cnt;
+                            }
+                        }
+                    }
+                    assertEquals(cnt, 1, "Expected only one listed line");
+                })
+        );
+    }
+
+    public void elideStartUpFromSave() throws IOException {
+        Compiler compiler = new Compiler();
+        Path path = compiler.getPath("myfile");
+        test(
+                (a) -> assertCommandCheckOutput(a, "123",
+                        (s) -> assertTrue(s.contains("type int"), s)),
+                (a) -> assertCommand(a, "/save " + path.toString(), "")
+        );
+        try (Stream<String> lines = Files.lines(path)) {
+            assertEquals(lines.count(), 1, "Expected only one saved line");
+        }
+    }
+
+    public void testInterrupt() {
+        ReplTest interrupt = (a) -> assertCommand(a, "\u0003", "");
+        for (String s : new String[] { "", "\u0003" }) {
+            test(false, new String[]{"-nostartup"},
+                    (a) -> assertCommand(a, "int a = 2 +" + s, ""),
+                    interrupt,
+                    (a) -> assertCommand(a, "int a\u0003", ""),
+                    (a) -> assertCommand(a, "int a = 2 + 2\u0003", ""),
+                    (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                    (a) -> evaluateExpression(a, "int", "2", "2"),
+                    (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                    (a) -> assertCommand(a, "void f() {", ""),
+                    (a) -> assertCommand(a, "int q = 10;" + s, ""),
+                    interrupt,
+                    (a) -> assertCommand(a, "void f() {}\u0003", ""),
+                    (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                    (a) -> assertMethod(a, "int f() { return 0; }", "()int", "f"),
+                    (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                    (a) -> assertCommand(a, "class A {" + s, ""),
+                    interrupt,
+                    (a) -> assertCommand(a, "class A {}\u0003", ""),
+                    (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                    (a) -> assertClass(a, "interface A {}", "interface", "A"),
+                    (a) -> assertCommandCheckOutput(a, "/c", assertClasses())
+            );
+        }
+    }
+
+    private final Object lock = new Object();
+    private PrintWriter out;
+    private boolean isStopped;
+    private Thread t;
+    private void assertStop(boolean after, String cmd, String output) {
+        if (!after) {
+            isStopped = false;
+            StringWriter writer = new StringWriter();
+            out = new PrintWriter(writer);
+            setCommandInput(cmd + "\n");
+            t = new Thread(() -> {
+                try {
+                    // no chance to know whether cmd is being evaluated
+                    Thread.sleep(5000);
+                } catch (InterruptedException ignored) {
+                }
+                int i = 1;
+                int n = 30;
+                synchronized (lock) {
+                    do {
+                        setCommandInput("\u0003");
+                        if (!isStopped) {
+                            out.println("Not stopped. Try again: " + i);
+                            try {
+                                lock.wait(1000);
+                            } catch (InterruptedException ignored) {
+                            }
+                        }
+                    } while (i++ < n && !isStopped);
+                    if (!isStopped) {
+                        System.err.println(writer.toString());
+                        fail("Evaluation was not stopped: '" + cmd + "'");
+                    }
+                }
+            });
+            t.start();
+        } else {
+            synchronized (lock)  {
+                out.println("Evaluation was stopped successfully: '" + cmd + "'");
+                isStopped = true;
+                lock.notify();
+            }
+            try {
+                t.join();
+                t = null;
+            } catch (InterruptedException ignored) {
+            }
+            assertOutput(getCommandOutput(), "", "command");
+            assertOutput(getCommandErrorOutput(), "", "command error");
+            assertOutput(getUserOutput(), output, "user");
+            assertOutput(getUserErrorOutput(), "", "user error");
+        }
+    }
+
+    public void testStop() {
+        test(
+                (a) -> assertStop(a, "while (true) {}", "Killed.\n"),
+                (a) -> assertStop(a, "while (true) { try { Thread.sleep(100); } catch (InterruptedException ex) { } }", "Killed.\n")
+        );
+    }
+
+    @Test(enabled = false) // TODO 8130450
+    public void testRerun() {
+        test(false, new String[] {"-nostartup"},
+                (a) -> assertCommand(a, "/0", "|  Cannot find snippet 0\n"),
+                (a) -> assertCommand(a, "/5", "|  Cannot find snippet 5\n")
+        );
+        String[] codes = new String[] {
+                "int a = 0;", // var
+                "class A {}", // class
+                "void f() {}", // method
+                "bool b;", // active failed
+                "void g() { h(); }", // active corralled
+        };
+        List<ReplTest> tests = new ArrayList<>();
+        for (String s : codes) {
+            tests.add((a) -> assertCommand(a, s, null));
+        }
+        for (int i = 0; i < codes.length; ++i) {
+            final int finalI = i;
+            Consumer<String> check = (s) -> {
+                String[] ss = s.split("\n");
+                assertEquals(ss[0], codes[finalI]);
+                assertTrue(ss.length > 1, s);
+            };
+            tests.add((a) -> assertCommandCheckOutput(a, "/" + (finalI + 1), check));
+        }
+        for (int i = 0; i < codes.length; ++i) {
+            final int finalI = i;
+            Consumer<String> check = (s) -> {
+                String[] ss = s.split("\n");
+                assertEquals(ss[0], codes[codes.length - finalI - 1]);
+                assertTrue(ss.length > 1, s);
+            };
+            tests.add((a) -> assertCommandCheckOutput(a, "/-" + (finalI + 1), check));
+        }
+        tests.add((a) -> assertCommandCheckOutput(a, "/!", assertStartsWith("void g() { h(); }")));
+        test(false, new String[]{"-nostartup"},
+                tests.toArray(new ReplTest[tests.size()]));
+    }
+
+    public void testRemaining() {
+        test(
+                (a) -> assertCommand(a, "int z; z =", "|  Added variable z of type int\n"),
+                (a) -> assertCommand(a, "5", "|  Variable z has been assigned the value 5\n"),
+                (a) -> assertCommand(a, "/*nada*/; int q =", ""),
+                (a) -> assertCommand(a, "77", "|  Added variable q of type int with initial value 77\n"),
+                (a) -> assertCommand(a, "//comment;", ""),
+                (a) -> assertCommand(a, "int v;", "|  Added variable v of type int\n"),
+                (a) -> assertCommand(a, "int v; int c", "|  Added variable c of type int\n")
+        );
+    }
+
+    public void testDebug() {
+        test(
+                (a) -> assertCommand(a, "/db", "|  Debugging on\n"),
+                (a) -> assertCommand(a, "/debug", "|  Debugging off\n"),
+                (a) -> assertCommand(a, "/debug", "|  Debugging on\n"),
+                (a) -> assertCommand(a, "/db", "|  Debugging off\n")
+        );
+    }
+
+    public void testHelp() {
+        Consumer<String> testOutput = (s) -> {
+            List<String> ss = Stream.of(s.split("\n"))
+                    .filter(l -> !l.isEmpty())
+                    .collect(Collectors.toList());
+            assertTrue(ss.size() >= 5, "Help does not print enough lines:\n" + s);
+        };
+        test(
+                (a) -> assertCommandCheckOutput(a, "/?", testOutput),
+                (a) -> assertCommandCheckOutput(a, "/help", testOutput)
+        );
+    }
+
+    public void oneLineOfError() {
+        test(
+                (a) -> assertCommand(a, "12+", null),
+                (a) -> assertCommandCheckOutput(a, "  true", (s) ->
+                        assertTrue(s.contains("12+") && !s.contains("true"), "Output: '" + s + "'"))
+        );
+    }
+
+    public void defineVariables() {
+        test(
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+                (a) -> assertVariable(a, "int", "a"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+                (a) -> assertVariable(a, "double", "a", "1", "1.0"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+                (a) -> evaluateExpression(a, "double", "2 * a", "2.0"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                (a) -> assertCommandCheckOutput(a, "/vars", assertVariables())
+        );
+    }
+
+    public void defineMethods() {
+        test(
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
+                (a) -> assertMethod(a, "int f() { return 0; }", "()int", "f"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
+                (a) -> assertMethod(a, "void f(int a) { g(); }", "(int)void", "f"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
+                (a) -> assertMethod(a, "void g() {}", "()void", "g"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods())
+        );
+    }
+
+    public void defineClasses() {
+        test(
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+                (a) -> assertClass(a, "class A { }", "class", "A"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+                (a) -> assertClass(a, "interface A { }", "interface", "A"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+                (a) -> assertClass(a, "enum A { }", "enum", "A"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                (a) -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+                (a) -> assertClass(a, "@interface A { }", "@interface", "A"),
+                (a) -> assertCommandCheckOutput(a, "/l", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/list", assertList()),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                (a) -> assertCommandCheckOutput(a, "/classes", assertClasses())
+        );
+    }
+
+    public void testClasspathDirectory() {
+        Compiler compiler = new Compiler();
+        Path outDir = Paths.get("testClasspathDirectory");
+        compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
+        Path classpath = compiler.getPath(outDir);
+        test(
+                (a) -> assertCommand(a, "/cp " + classpath, String.format("|  Path %s added to classpath\n", classpath)),
+                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"A\"")
+        );
+        test(new String[] { "-cp", classpath.toString() },
+                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"A\"")
+        );
+        test(new String[] { "-classpath", classpath.toString() },
+                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"A\"")
+        );
+    }
+
+    public void testClasspathJar() {
+        Compiler compiler = new Compiler();
+        Path outDir = Paths.get("testClasspathJar");
+        compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
+        String jarName = "test.jar";
+        compiler.jar(outDir, jarName, "pkg/A.class");
+        Path jarPath = compiler.getPath(outDir).resolve(jarName);
+        test(
+                (a) -> assertCommand(a, "/classpath " + jarPath, String.format("|  Path %s added to classpath\n", jarPath)),
+                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"A\"")
+        );
+        test(new String[] { "-cp", jarPath.toString() },
+                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"A\"")
+        );
+        test(new String[] { "-classpath", jarPath.toString() },
+                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"A\"")
+        );
+    }
+
+    public void testStartupFileOption() {
+        try {
+            Compiler compiler = new Compiler();
+            Path startup = compiler.getPath("StartupFileOption/startup.txt");
+            compiler.writeToFile(startup, "class A { public String toString() { return \"A\"; } }");
+            test(new String[]{"-startup", startup.toString()},
+                    (a) -> evaluateExpression(a, "A", "new A()", "\"A\"\n")
+            );
+            test(new String[]{"-nostartup"},
+                    (a) -> assertCommandCheckOutput(a, "printf(\"\")", assertStartsWith("|  Error:\n|  cannot find symbol"))
+            );
+            test((a) -> assertCommand(a, "printf(\"A\")", "", "", null, "A", ""));
+            test(false, new String[]{"-startup", "UNKNOWN"}, "|  File 'UNKNOWN' for start-up is not found.");
+        } finally {
+            removeStartup();
+        }
+    }
+
+    public void testLoadingFromArgs() {
+        Compiler compiler = new Compiler();
+        Path path = compiler.getPath("loading.repl");
+        compiler.writeToFile(path, "int a = 10; double x = 20; double a = 10;");
+        test(new String[] { path.toString() },
+                (a) -> assertCommand(a, "x", "|  Variable x of type double has value 20.0\n"),
+                (a) -> assertCommand(a, "a", "|  Variable a of type double has value 10.0\n")
+        );
+        Path unknown = compiler.getPath("UNKNOWN.jar");
+        test(true, new String[]{unknown.toString()},
+                "|  File '" + unknown
+                + "' is not found: " + unknown
+                + " (No such file or directory)\n");
+    }
+
+    public void testReset() {
+        test(
+                (a) -> assertReset(a, "/r"),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertVariable(a, "int", "x"),
+                (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                (a) -> assertMethod(a, "void f() { }", "()void", "f"),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertClass(a, "class A { }", "class", "A"),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses()),
+                (a) -> assertReset(a, "/reset"),
+                (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                (a) -> assertCommandCheckOutput(a, "/c", assertClasses())
+        );
+    }
+
+    public void testOpen() {
+        Compiler compiler = new Compiler();
+        Path path = compiler.getPath("testOpen.repl");
+        compiler.writeToFile(path,
+                "int a = 10;\ndouble x = 20;\ndouble a = 10;\n" +
+                        "class A { public String toString() { return \"A\"; } }");
+        for (String s : new String[]{"/o", "/open"}) {
+            test(
+                    (a) -> assertCommand(a, s + " " + path.toString(), ""),
+                    (a) -> assertCommand(a, "a", "|  Variable a of type double has value 10.0\n"),
+                    (a) -> evaluateExpression(a, "A", "new A();", "\"A\""),
+                    (a) -> {
+                        loadVariable(a, "double", "x", "20.0", "20.0");
+                        loadVariable(a, "double", "a", "10.0", "10.0");
+                        loadVariable(a, "A", "$6", "new A();", "A");
+                        loadClass(a, "class A { public String toString() { return \"A\"; } }",
+                                "class", "A");
+                        assertCommandCheckOutput(a, "/c", assertClasses());
+                    },
+                    (a) -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                    (a) -> assertCommandCheckOutput(a, "/v", assertVariables())
+            );
+            Path unknown = compiler.getPath("UNKNOWN.repl");
+            test(
+                    (a) -> assertCommand(a, s + " " + unknown,
+                            "|  File '" + unknown
+                                    + "' is not found: " + unknown
+                                    + " (No such file or directory)\n")
+            );
+        }
+    }
+
+    public void testSave() throws IOException {
+        Compiler compiler = new Compiler();
+        Path path = compiler.getPath("testSave.repl");
+        List<String> list = Arrays.asList(
+                "int a;",
+                "class A { public String toString() { return \"A\"; } }"
+        );
+        for (String s : new String[]{"/s", "/save"}) {
+            test(
+                    (a) -> assertVariable(a, "int", "a"),
+                    (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"),
+                    (a) -> assertCommand(a, s + " " + path.toString(), "")
+            );
+            assertEquals(Files.readAllLines(path), list);
+        }
+        for (String s : new String[]{"/s", "/save"}) {
+            List<String> output = new ArrayList<>();
+            test(
+                    (a) -> assertCommand(a, "int a;", null),
+                    (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"),
+                    (a) -> assertCommandCheckOutput(a, "/list all", (out) ->
+                            output.addAll(Stream.of(out.split("\n"))
+                                    .filter(str -> !str.isEmpty())
+                                    .map(str -> str.substring(str.indexOf(':') + 2))
+                                    .filter(str -> !str.startsWith("/"))
+                                    .collect(Collectors.toList()))),
+                    (a) -> assertCommand(a, s + " all " + path.toString(), "")
+            );
+            assertEquals(Files.readAllLines(path), output);
+        }
+        for (String s : new String[]{"/s", "/save"}) {
+            List<String> output = new ArrayList<>();
+            test(
+                    (a) -> assertVariable(a, "int", "a"),
+                    (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"),
+                    (a) -> assertCommandCheckOutput(a, "/h", (out) ->
+                            output.addAll(Stream.of(out.split("\n"))
+                                    .filter(str -> !str.isEmpty())
+                                    .collect(Collectors.toList()))),
+                    (a) -> assertCommand(a, s + " history " + path.toString(), "")
+            );
+            output.add(s + " history " + path.toString());
+            assertEquals(Files.readAllLines(path), output);
+        }
+    }
+
+    public void testStartSet() throws BackingStoreException {
+        try {
+            Compiler compiler = new Compiler();
+            Path startUpFile = compiler.getPath("startUp.txt");
+            test(
+                    (a) -> assertVariable(a, "int", "a"),
+                    (a) -> assertVariable(a, "double", "b", "10", "10.0"),
+                    (a) -> assertMethod(a, "void f() {}", "()V", "f"),
+                    (a) -> assertCommand(a, "/s " + startUpFile.toString(), null),
+                    (a) -> assertCommand(a, "/setstart " + startUpFile.toString(), null)
+            );
+            Path unknown = compiler.getPath("UNKNOWN");
+            test(
+                    (a) -> assertCommand(a, "/setstart " + unknown.toString(),
+                            "|  File '" + unknown + "' for /setstart is not found.\n")
+            );
+            test(false, new String[0],
+                    (a) -> {
+                        loadVariable(a, "int", "a");
+                        loadVariable(a, "double", "b", "10.0", "10.0");
+                        loadMethod(a, "void f() {}", "()void", "f");
+                        assertCommandCheckOutput(a, "/c", assertClasses());
+                    },
+                    (a) -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                    (a) -> assertCommandCheckOutput(a, "/m", assertMethods())
+            );
+        } finally {
+            removeStartup();
+        }
+    }
+
+    private void removeStartup() {
+        Preferences preferences = Preferences.userRoot().node("tool/REPL");
+        if (preferences != null) {
+            preferences.remove("STARTUP");
+        }
+    }
+
+    public void testUnknownCommand() {
+        test((a) -> assertCommand(a, "/unknown",
+                "|  No such command: /unknown\n" +
+                "|  Type /help for help.\n"));
+    }
+
+    public void testEmptyClassPath() {
+        String[] commands = {"/cp", "/classpath"};
+        test(Stream.of(commands)
+                .map(cmd -> (ReplTest) after -> assertCommand(after, cmd, "|  /classpath requires a path argument\n"))
+                .toArray(ReplTest[]::new));
+
+    }
+
+    public void testNoArgument() {
+        String[] commands = {"/s", "/save", "/o", "/open", "/setstart", "/savestart"};
+        test(Stream.of(commands)
+                .map(cmd -> {
+                    String c = cmd;
+                    if ("/s".equals(cmd)) {
+                        c = "/save";
+                    }
+                    if ("/o".equals(cmd)) {
+                        c = "/open";
+                    }
+                    final String finalC = c;
+                    return (ReplTest) after -> assertCommand(after, cmd,
+                            "|  The " + finalC + " command requires a filename argument.\n");
+                })
+                .toArray(ReplTest[]::new));
+    }
+
+    public void testStartSave() throws IOException {
+        Compiler compiler = new Compiler();
+        Path startSave = compiler.getPath("startSave.txt");
+        test(a -> assertCommand(a, "/savestart " + startSave.toString(), null));
+        List<String> lines = Files.lines(startSave)
+                .filter(s -> !s.isEmpty())
+                .collect(Collectors.toList());
+        assertEquals(lines, Arrays.asList(
+                "import java.util.*;",
+                "import java.io.*;",
+                "import java.math.*;",
+                "import java.net.*;",
+                "import java.util.concurrent.*;",
+                "import java.util.prefs.*;",
+                "import java.util.regex.*;",
+                "void printf(String format, Object... args) { System.out.printf(format, args); }"));
+    }
+
+    public void testConstrainedUpdates() {
+        test(
+                a -> assertClass(a, "class XYZZY { }", "class", "XYZZY"),
+                a -> assertVariable(a, "XYZZY", "xyzzy"),
+                a -> assertCommandCheckOutput(a, "import java.util.stream.*",
+                        (out) -> assertTrue(out.trim().isEmpty(), "Expected no output, got: " + out))
+        );
+    }
+
+    public void testRemoteExit() {
+        test(
+                a -> assertVariable(a, "int", "x"),
+                a -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                a -> assertCommandCheckOutput(a, "System.exit(5);",  s ->
+                        assertTrue(s.contains("terminated"), s)),
+                a -> assertCommandCheckOutput(a, "/v", s ->
+                        assertTrue(s.trim().isEmpty(), s)),
+                a -> assertMethod(a, "void f() { }", "()void", "f"),
+                a -> assertCommandCheckOutput(a, "/m", assertMethods())
+        );
+    }
+
+    public void testListArgs() {
+        Consumer<String> assertList = s -> assertTrue(s.split("\n").length >= 7, s);
+        String arg = "qqqq";
+        Consumer<String> assertError = s -> assertEquals(s, "|  Invalid /list argument: " + arg + "\n");
+        test(
+                a -> assertCommandCheckOutput(a, "/l all", assertList),
+                a -> assertCommandCheckOutput(a, "/list all", assertList),
+                a -> assertCommandCheckOutput(a, "/l " + arg, assertError),
+                a -> assertCommandCheckOutput(a, "/list " + arg, assertError),
+                a -> assertVariable(a, "int", "a"),
+                a -> assertCommandCheckOutput(a, "/l history", assertList),
+                a -> assertCommandCheckOutput(a, "/list history", assertList)
+        );
+    }
+
+    public void testFeedbackNegative() {
+        for (String feedback : new String[]{"/f", "/feedback"}) {
+            test(a -> assertCommandCheckOutput(a, feedback + " aaaa",
+                    assertStartsWith("|  Follow /feedback with of the following")));
+        }
+    }
+
+    public void testFeedbackOff() {
+        for (String feedback : new String[]{"/f", "/feedback"}) {
+            for (String off : new String[]{"o", "off"}) {
+                test(
+                        a -> assertCommand(a, feedback + " " + off, ""),
+                        a -> assertCommand(a, "int a", ""),
+                        a -> assertCommand(a, "void f() {}", ""),
+                        a -> assertCommandCheckOutput(a, "aaaa", assertStartsWith("|  Error:")),
+                        a -> assertCommandCheckOutput(a, "public void f() {}", assertStartsWith("|  Warning:"))
+                );
+            }
+        }
+    }
+
+    public void testFeedbackConcise() {
+        Compiler compiler = new Compiler();
+        Path testConciseFile = compiler.getPath("testConciseFeedback");
+        String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"};
+        compiler.writeToFile(testConciseFile, sources);
+        for (String feedback : new String[]{"/f", "/feedback"}) {
+            for (String concise : new String[]{"c", "concise"}) {
+                test(
+                        a -> assertCommand(a, feedback + " " + concise, ""),
+                        a -> assertCommand(a, sources[0], ""),
+                        a -> assertCommand(a, sources[1], ""),
+                        a -> assertCommand(a, sources[2], ""),
+                        a -> assertCommand(a, sources[3], "|  a : 10\n"),
+                        a -> assertCommand(a, "/o " + testConciseFile.toString(), "|  a : 10\n")
+                );
+            }
+        }
+    }
+
+    public void testFeedbackNormal() {
+        Compiler compiler = new Compiler();
+        Path testNormalFile = compiler.getPath("testConciseNormal");
+        String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"};
+        String[] sources2 = new String[] {"int a //again", "void f() {int y = 4;}", "class A {} //again", "a = 10"};
+        String[] output = new String[] {
+                "|  Added variable a of type int\n",
+                "|  Added method f()\n",
+                "|  Added class A\n",
+                "|  Variable a has been assigned the value 10\n"
+        };
+        compiler.writeToFile(testNormalFile, sources2);
+        for (String feedback : new String[]{"/f", "/feedback"}) {
+            for (String feedbackState : new String[]{"n", "normal", "v", "verbose"}) {
+                String f = null;
+                if (feedbackState.startsWith("n")) {
+                    f = "normal";
+                } else if (feedbackState.startsWith("v")) {
+                    f = "verbose";
+                }
+                final String finalF = f;
+                test(
+                        a -> assertCommand(a, feedback + " " + feedbackState, "|  Feedback mode: " + finalF +"\n"),
+                        a -> assertCommand(a, sources[0], output[0]),
+                        a -> assertCommand(a, sources[1], output[1]),
+                        a -> assertCommand(a, sources[2], output[2]),
+                        a -> assertCommand(a, sources[3], output[3]),
+                        a -> assertCommand(a, "/o " + testNormalFile.toString(),
+                                "|  Modified variable a of type int\n" +
+                                "|  Modified method f()\n" +
+                                "|    Update overwrote method f()\n" +
+                                "|  Modified class A\n" +
+                                "|    Update overwrote class A\n" +
+                                "|  Variable a has been assigned the value 10\n")
+                );
+            }
+        }
+    }
+
+    public void testFeedbackDefault() {
+        Compiler compiler = new Compiler();
+        Path testDefaultFile = compiler.getPath("testDefaultFeedback");
+        String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"};
+        String[] output = new String[] {
+                "|  Added variable a of type int\n",
+                "|  Added method f()\n",
+                "|  Added class A\n",
+                "|  Variable a has been assigned the value 10\n"
+        };
+        compiler.writeToFile(testDefaultFile, sources);
+        for (String feedback : new String[]{"/f", "/feedback"}) {
+            for (String defaultFeedback : new String[]{"", "d", "default"}) {
+                test(
+                        a -> assertCommand(a, "/f o", ""),
+                        a -> assertCommand(a, "int x", ""),
+                        a -> assertCommand(a, feedback + " " + defaultFeedback, "|  Feedback mode: default\n"),
+                        a -> assertCommand(a, sources[0], output[0]),
+                        a -> assertCommand(a, sources[1], output[1]),
+                        a -> assertCommand(a, sources[2], output[2]),
+                        a -> assertCommand(a, sources[3], output[3]),
+                        a -> assertCommand(a, "/o " + testDefaultFile.toString(), "")
+                );
+            }
+        }
+    }
+
+    public void testDrop() {
+        for (String drop : new String[]{"/d", "/drop"}) {
+            test(false, new String[]{"-nostartup"},
+                    a -> assertVariable(a, "int", "a"),
+                    a -> dropVariable(a, drop + " 1", "int a = 0"),
+                    a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
+                    a -> dropMethod(a, drop + " 2", "b ()I"),
+                    a -> assertClass(a, "class A {}", "class", "A"),
+                    a -> dropClass(a, drop + " 3", "class A"),
+                    a -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                    a -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                    a -> assertCommandCheckOutput(a, "/c", assertClasses())
+            );
+            test(false, new String[]{"-nostartup"},
+                    a -> assertVariable(a, "int", "a"),
+                    a -> dropVariable(a, drop + " a", "int a = 0"),
+                    a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
+                    a -> dropMethod(a, drop + " b", "b ()I"),
+                    a -> assertClass(a, "class A {}", "class", "A"),
+                    a -> dropClass(a, drop + " A", "class A"),
+                    a -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                    a -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                    a -> assertCommandCheckOutput(a, "/c", assertClasses())
+            );
+        }
+    }
+
+    public void testDropNegative() {
+        for (String drop : new String[]{"/d", "/drop"}) {
+            test(false, new String[]{"-nostartup"},
+                    a -> assertCommand(a, drop + " 0", "|  No definition or id named 0 found.  See /classes /methods /vars or /list\n"),
+                    a -> assertCommand(a, drop + " a", "|  No definition or id named a found.  See /classes /methods /vars or /list\n"),
+                    a -> assertCommandCheckOutput(a, drop,
+                            assertStartsWith("|  In the /drop argument, please specify an import, variable, method, or class to drop.")),
+                    a -> assertVariable(a, "int", "a"),
+                    a -> assertCommand(a, "a", "|  Variable a of type int has value 0\n"),
+                    a -> assertCommand(a, drop + " 2", "|  The argument did not specify an import, variable, method, or class to drop.\n")
+            );
+        }
+    }
+
+    public void testAmbiguousDrop() {
+        Consumer<String> check = s -> {
+            assertTrue(s.startsWith("|  The argument references more than one import, variable, method, or class"), s);
+            int lines = s.split("\n").length;
+            assertEquals(lines, 5, "Expected 3 ambiguous keys, but found: " + (lines - 2) + "\n" + s);
+        };
+        for (String drop : new String[]{"/d", "/drop"}) {
+            test(
+                    a -> assertVariable(a, "int", "a"),
+                    a -> assertMethod(a, "int a() { return 0; }", "()int", "a"),
+                    a -> assertClass(a, "class a {}", "class", "a"),
+                    a -> assertCommandCheckOutput(a, drop + " a", check),
+                    a -> assertCommandCheckOutput(a, "/v", assertVariables()),
+                    a -> assertCommandCheckOutput(a, "/m", assertMethods()),
+                    a -> assertCommandCheckOutput(a, "/c", assertClasses())
+            );
+            test(
+                    a -> assertMethod(a, "int a() { return 0; }", "()int", "a"),
+                    a -> assertMethod(a, "double a(int a) { return 0; }", "(int)double", "a"),
+                    a -> assertMethod(a, "double a(double a) { return 0; }", "(double)double", "a"),
+                    a -> assertCommandCheckOutput(a, drop + " a", check),
+                    a -> assertCommandCheckOutput(a, "/m", assertMethods())
+            );
+        }
+    }
+
+    public void testHistoryReference() {
+        test(false, new String[]{"-nostartup"},
+                a -> assertCommand(a, "System.err.println(1)", "", "", null, "", "1\n"),
+                a -> assertCommand(a, "System.err.println(2)", "", "", null, "", "2\n"),
+                a -> assertCommand(a, "/-2", "System.err.println(1)\n", "", null, "", "1\n"),
+                a -> assertCommand(a, "/history", "\n" +
+                                                    "/debug 0\n" +
+                                                    "System.err.println(1)\n" +
+                                                    "System.err.println(2)\n" +
+                                                    "System.err.println(1)\n" +
+                                                    "/history\n"),
+                a -> assertCommand(a, "/-2", "System.err.println(2)\n", "", null, "", "2\n"),
+                a -> assertCommand(a, "/!", "System.err.println(2)\n", "", null, "", "2\n"),
+                a -> assertCommand(a, "/2", "System.err.println(2)\n", "", null, "", "2\n"),
+                a -> assertCommand(a, "/1", "System.err.println(1)\n", "", null, "", "1\n")
+        );
+    }
+}
diff --git a/langtools/test/jdk/jshell/TypeNameTest.java b/langtools/test/jdk/jshell/TypeNameTest.java
new file mode 100644
index 0000000..41dbe70
--- /dev/null
+++ b/langtools/test/jdk/jshell/TypeNameTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 null test
+ * @build KullaTesting TestingInputStream
+ * @run testng TypeNameTest
+ */
+
+import jdk.jshell.Snippet;
+import jdk.jshell.VarSnippet;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.VALID;
+import static org.testng.Assert.assertEquals;
+import static jdk.jshell.Snippet.Status.OVERWRITTEN;
+
+@Test
+public class TypeNameTest extends KullaTesting {
+
+    public void testReplClassName() {
+        assertEval("class C {}");
+        VarSnippet sn = (VarSnippet) varKey(assertEval("new C();"));
+        assertEquals(sn.typeName(), "C");
+    }
+
+    public void testReplNestedClassName() {
+        assertEval("class D { static class E {} }");
+        VarSnippet sn = (VarSnippet) varKey(assertEval("new D.E();"));
+        assertEquals(sn.typeName(), "D.E");
+    }
+
+    public void testAnonymousClassName() {
+        assertEval("class C {}");
+        VarSnippet sn = (VarSnippet) varKey(assertEval("new C() { int x; };"));
+        assertEquals(sn.typeName(), "C");
+    }
+
+    public void testCapturedTypeName() {
+        VarSnippet sn = (VarSnippet) varKey(assertEval("\"\".getClass();"));
+        assertEquals(sn.typeName(), "Class<? extends String>");
+    }
+
+    public void testJavaLang() {
+        VarSnippet sn = (VarSnippet) varKey(assertEval("\"\";"));
+        assertEquals(sn.typeName(), "String");
+    }
+
+    public void testNotOverEagerPackageEating() {
+        VarSnippet sn = (VarSnippet) varKey(assertEval("\"\".getClass().getDeclaredMethod(\"hashCode\");"));
+        assertEquals(sn.typeName(), "java.lang.reflect.Method");
+    }
+
+    public void testBounds() {
+        assertEval("java.util.List<? extends String> list1 = java.util.Arrays.asList(\"\");");
+        VarSnippet sn1 = (VarSnippet) varKey(assertEval("list1.iterator().next()"));
+        assertEquals(sn1.typeName(), "String");
+        assertEval("java.util.List<? super String> list2 = java.util.Arrays.asList(\"\");");
+        VarSnippet sn2 = (VarSnippet) varKey(assertEval("list2.iterator().next()"));
+        assertEquals(sn2.typeName(), "Object");
+        assertEval("java.util.List<?> list3 = java.util.Arrays.asList(\"\");");
+        VarSnippet sn3 = (VarSnippet) varKey(assertEval("list3.iterator().next()"));
+        assertEquals(sn3.typeName(), "Object");
+        assertEval("class Test1<X extends CharSequence> { public X get() { return null; } }");
+        Snippet x = varKey(assertEval("Test1<?> x = new Test1<>();"));
+        VarSnippet sn4 = (VarSnippet) varKey(assertEval("x.get()"));
+        assertEquals(sn4.typeName(), "CharSequence");
+        assertEval("class Foo<X extends Number & CharSequence> { public X get() { return null; } }");
+        assertEval("Foo<?> x = new Foo<>();",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        VarSnippet sn5 = (VarSnippet) varKey(assertEval("x.get()"));
+        assertEquals(sn5.typeName(), "Object");
+    }
+}
diff --git a/langtools/test/jdk/jshell/VariablesTest.java b/langtools/test/jdk/jshell/VariablesTest.java
new file mode 100644
index 0000000..73a25a3
--- /dev/null
+++ b/langtools/test/jdk/jshell/VariablesTest.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 Tests for EvaluationState.variables
+ * @build KullaTesting TestingInputStream ExpectedDiagnostic
+ * @run testng VariablesTest
+ */
+
+import java.util.List;
+import javax.tools.Diagnostic;
+
+import jdk.jshell.Snippet;
+import jdk.jshell.TypeDeclSnippet;
+import jdk.jshell.VarSnippet;
+import jdk.jshell.Snippet.SubKind;
+import jdk.jshell.SnippetEvent;
+import org.testng.annotations.Test;
+
+import static jdk.jshell.Snippet.Status.*;
+import static jdk.jshell.Snippet.SubKind.VAR_DECLARATION_SUBKIND;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+@Test
+public class VariablesTest extends KullaTesting {
+
+    public void noVariables() {
+        assertNumberOfActiveVariables(0);
+    }
+
+    private void badVarValue(VarSnippet key) {
+        try {
+            getState().varValue(key);
+            fail("Expected exception for: " + key.source());
+        } catch (IllegalArgumentException e) {
+            // ok
+        }
+    }
+
+    public void testVarValue1() {
+        VarSnippet v1 = varKey(assertEval("und1 a;", added(RECOVERABLE_NOT_DEFINED)));
+        badVarValue(v1);
+        VarSnippet v2 = varKey(assertEval("und2 a;",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(v1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        badVarValue(v2);
+        TypeDeclSnippet und = classKey(assertEval("class und2 {}",
+                added(VALID),
+                ste(v2, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)));
+        assertVarValue(v2, "null");
+        assertDrop(und,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(und, VALID, DROPPED, true, null),
+                ste(v2, VALID, RECOVERABLE_NOT_DEFINED, true, und));
+        badVarValue(v1);
+        badVarValue(v2);
+    }
+
+    public void testVarValue2() {
+        VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
+        badVarValue(v1);
+        VarSnippet v2 = varKey(assertEval("int a = 0;", ste(v1, REJECTED, VALID, true, null)));
+        assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
+        badVarValue(v2);
+    }
+
+    public void testSignature1() {
+        VarSnippet v1 = varKey(assertEval("und1 a;", added(RECOVERABLE_NOT_DEFINED)));
+        assertVariableDeclSnippet(v1, "a", "und1", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+        VarSnippet v2 = varKey(assertEval("und2 a;",
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, RECOVERABLE_NOT_DEFINED, false, null),
+                ste(v1, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertVariableDeclSnippet(v2, "a", "und2", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+        TypeDeclSnippet und = classKey(assertEval("class und2 {}",
+                added(VALID),
+                ste(v2, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET)));
+        assertVariableDeclSnippet(v2, "a", "und2", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
+        assertDrop(und,
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                ste(und, VALID, DROPPED, true, null),
+                ste(v2, VALID, RECOVERABLE_NOT_DEFINED, true, und));
+        assertVariableDeclSnippet(v2, "a", "und2", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+    }
+
+    public void testSignature2() {
+        VarSnippet v1 = (VarSnippet) assertDeclareFail("int a = 0.0;", "compiler.err.prob.found.req");
+        assertVariableDeclSnippet(v1, "a", "int", REJECTED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 1);
+        VarSnippet v2 = varKey(assertEval("int a = 0;",
+                ste(v1, REJECTED, VALID, true, null)));
+        assertVariableDeclSnippet(v2, "a", "int", VALID, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
+        assertDrop(v2, ste(MAIN_SNIPPET, VALID, DROPPED, true, null));
+        assertVariableDeclSnippet(v2, "a", "int", DROPPED, SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND, 0, 0);
+    }
+
+    public void variables() {
+        VarSnippet snx = varKey(assertEval("int x = 10;"));
+        VarSnippet sny = varKey(assertEval("String y = \"hi\";"));
+        VarSnippet snz = varKey(assertEval("long z;"));
+        assertVariables(variable("int", "x"), variable("String", "y"), variable("long", "z"));
+        assertVarValue(snx, "10");
+        assertVarValue(sny, "\"hi\"");
+        assertVarValue(snz, "0");
+        assertActiveKeys();
+    }
+
+    public void variablesArray() {
+        VarSnippet sn = varKey(assertEval("int[] a = new int[12];"));
+        assertEquals(sn.typeName(), "int[]");
+        assertEval("int len = a.length;", "12");
+        assertVariables(variable("int[]", "a"), variable("int", "len"));
+        assertActiveKeys();
+    }
+
+    public void variablesArrayOld() {
+        VarSnippet sn = varKey(assertEval("int a[] = new int[12];"));
+        assertEquals(sn.typeName(), "int[]");
+        assertEval("int len = a.length;", "12");
+        assertVariables(variable("int[]", "a"), variable("int", "len"));
+        assertActiveKeys();
+    }
+
+    public void variablesRedefinition() {
+        Snippet x = varKey(assertEval("int x = 10;"));
+        Snippet y = varKey(assertEval("String y = \"\";", added(VALID)));
+        assertVariables(variable("int", "x"), variable("String", "y"));
+        assertActiveKeys();
+        assertEval("long x;",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(x, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("long", "x"), variable("String", "y"));
+        assertActiveKeys();
+        assertEval("String y;",
+                ste(MAIN_SNIPPET, VALID, VALID, false, null),
+                ste(y, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("long", "x"), variable("String", "y"));
+        assertActiveKeys();
+    }
+
+    public void variablesTemporary() {
+        assertEval("int $1 = 10;", added(VALID));
+        assertEval("2 * $1;", added(VALID));
+        assertVariables(variable("int", "$1"), variable("int", "$2"));
+        assertActiveKeys();
+        assertEval("String y;", added(VALID));
+        assertVariables(variable("int", "$1"), variable("int", "$2"), variable("String", "y"));
+        assertActiveKeys();
+    }
+
+    public void variablesTemporaryNull() {
+        assertEval("null;", added(VALID));
+        assertVariables(variable("Object", "$1"));
+        assertEval("(String) null;", added(VALID));
+        assertVariables(variable("Object", "$1"), variable("String", "$2"));
+        assertActiveKeys();
+        assertEval("\"\";", added(VALID));
+        assertVariables(
+                variable("Object", "$1"),
+                variable("String", "$2"),
+                variable("String", "$3"));
+        assertActiveKeys();
+    }
+
+    public void variablesClassReplace() {
+        assertEval("import java.util.*;", added(VALID));
+        Snippet var = varKey(assertEval("List<Integer> list = new ArrayList<>();", "[]",
+                added(VALID)));
+        assertVariables(variable("List<Integer>", "list"));
+        assertEval("class List {}",
+                DiagCheck.DIAG_OK,
+                DiagCheck.DIAG_ERROR,
+                added(VALID),
+                ste(var, VALID, RECOVERABLE_NOT_DEFINED, true, MAIN_SNIPPET));
+        assertVariables();
+        assertEval("List list = new List();",
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_IGNORE,
+                ste(MAIN_SNIPPET, RECOVERABLE_NOT_DEFINED, VALID, true, null),
+                ste(var, RECOVERABLE_NOT_DEFINED, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("List", "list"));
+        assertActiveKeys();
+    }
+
+    public void variablesErrors() {
+        assertDeclareFail("String;", new ExpectedDiagnostic("compiler.err.cant.resolve.location", 0, 6, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+    }
+
+    public void variablesUnresolvedActiveFailed() {
+        VarSnippet key = varKey(assertEval("und x;", added(RECOVERABLE_NOT_DEFINED)));
+        assertVariableDeclSnippet(key, "x", "und", RECOVERABLE_NOT_DEFINED, VAR_DECLARATION_SUBKIND, 1, 0);
+        assertUnresolvedDependencies1(key, RECOVERABLE_NOT_DEFINED, "class und");
+        assertNumberOfActiveVariables(1);
+        assertActiveKeys();
+    }
+
+    public void variablesUnresolvedError() {
+        assertDeclareFail("und y = null;", new ExpectedDiagnostic("compiler.err.cant.resolve.location", 0, 3, 0, -1, -1, Diagnostic.Kind.ERROR));
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+    }
+
+    public void variablesMultiByteCharacterType() {
+        assertEval("class \u3042 {}");
+        assertEval("\u3042 \u3042 = null;", added(VALID));
+        assertVariables(variable("\u3042", "\u3042"));
+        assertEval("new \u3042()", added(VALID));
+        assertVariables(variable("\u3042", "\u3042"), variable("\u3042", "$1"));
+
+        assertEval("class \u3042\u3044\u3046\u3048\u304a {}");
+        assertEval("\u3042\u3044\u3046\u3048\u304a \u3042\u3044\u3046\u3048\u304a = null;", added(VALID));
+        assertVariables(variable("\u3042", "\u3042"), variable("\u3042", "$1"),
+                variable("\u3042\u3044\u3046\u3048\u304a", "\u3042\u3044\u3046\u3048\u304a"));
+        assertEval("new \u3042\u3044\u3046\u3048\u304a();");
+        assertVariables(variable("\u3042", "\u3042"), variable("\u3042", "$1"),
+                variable("\u3042\u3044\u3046\u3048\u304a", "\u3042\u3044\u3046\u3048\u304a"),
+                variable("\u3042\u3044\u3046\u3048\u304a", "$2"));
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081689
+    public void methodVariablesAreNotVisible() {
+        Snippet foo = varKey(assertEval("int foo() {" +
+                        "int x = 10;" +
+                        "int y = 2 * x;" +
+                        "return x * y;" +
+                        "}", added(VALID)));
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+        assertEval("int x = 10;", "10");
+        assertEval("int foo() {" +
+                        "int y = 2 * x;" +
+                        "return x * y;" +
+                        "}",
+                ste(foo, VALID, VALID, false, null));
+        assertVariables(variable("int", "x"));
+        assertActiveKeys();
+        assertEval("foo();", "200");
+        assertVariables(variable("int", "x"), variable("int", "$1"));
+        assertActiveKeys();
+    }
+
+    @Test(enabled = false) // TODO 8081689
+    public void classFieldsAreNotVisible() {
+        Snippet key = classKey(assertEval("class clazz {" +
+                        "int x = 10;" +
+                        "int y = 2 * x;" +
+                        "}"));
+        assertNumberOfActiveVariables(0);
+        assertEval("int x = 10;", "10");
+        assertActiveKeys();
+        assertEval(
+                "class clazz {" +
+                        "int y = 2 * x;" +
+                        "}",
+                ste(key, VALID, VALID, true, null));
+        assertVariables(variable("int", "x"));
+        assertEval("new clazz().y;", "20");
+        assertVariables(variable("int", "x"), variable("int", "$1"));
+        assertActiveKeys();
+    }
+
+    public void multiVariables() {
+        List<SnippetEvent> abc = assertEval("int a, b, c = 10;",
+                DiagCheck.DIAG_OK, DiagCheck.DIAG_OK,
+                chain(added(VALID)),
+                chain(added(VALID)),
+                chain(added(VALID)));
+        Snippet a = abc.get(0).snippet();
+        Snippet b = abc.get(1).snippet();
+        Snippet c = abc.get(2).snippet();
+        assertVariables(variable("int", "a"), variable("int", "b"), variable("int", "c"));
+        assertEval("double a = 1.4, b = 8.8;", DiagCheck.DIAG_OK, DiagCheck.DIAG_OK,
+                chain(ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)),
+                chain(ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(b, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        assertVariables(variable("double", "a"), variable("double", "b"), variable("int", "c"));
+        assertEval("double c = a + b;",
+                ste(MAIN_SNIPPET, VALID, VALID, true, null),
+                ste(c, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
+        assertVariables(variable("double", "a"), variable("double", "b"), variable("double", "c"));
+        assertActiveKeys();
+    }
+
+    public void syntheticVariables() {
+        assertEval("assert false;");
+        assertNumberOfActiveVariables(0);
+        assertActiveKeys();
+    }
+
+    public void undefinedReplaceVariable() {
+        Snippet key = varKey(assertEval("int d = 234;", "234"));
+        assertVariables(variable("int", "d"));
+        String src = "undefined d;";
+        Snippet undefKey = varKey(assertEval(src,
+                ste(MAIN_SNIPPET, VALID, RECOVERABLE_NOT_DEFINED, true, null),
+                ste(key, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
+        //assertEquals(getState().source(snippet), src);
+        //assertEquals(snippet, undefKey);
+        assertEquals(getState().status(undefKey), RECOVERABLE_NOT_DEFINED);
+        List<String> unr = getState().unresolvedDependencies((VarSnippet) undefKey);
+        assertEquals(unr.size(), 1);
+        assertEquals(unr.get(0), "class undefined");
+        assertVariables(variable("undefined", "d"));
+    }
+
+    public void variableTypeName() {
+        assertEquals(varKey(assertEval("\"x\"")).typeName(), "String");
+
+        assertEquals(varKey(assertEval("java.util.regex.Pattern.compile(\"x\")")).typeName(), "java.util.regex.Pattern");
+        assertEval("import java.util.regex.*;", added(VALID));
+        assertEquals(varKey(assertEval("java.util.regex.Pattern.compile(\"x\")")).typeName(), "Pattern");
+
+        assertEquals(varKey(assertEval("new java.util.ArrayList()")).typeName(), "java.util.ArrayList");
+        assertEval("import java.util.ArrayList;", added(VALID));
+        assertEquals(varKey(assertEval("new java.util.ArrayList()")).typeName(), "ArrayList");
+
+        assertEquals(varKey(assertEval("java.util.Locale.Category.FORMAT")).typeName(), "java.util.Locale.Category");
+        assertEval("import static java.util.Locale.Category;", added(VALID));
+        assertEquals(varKey(assertEval("java.util.Locale.Category.FORMAT")).typeName(), "Category");
+    }
+}
diff --git a/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java
index 61c5e56..1e12cb8 100644
--- a/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java
+++ b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -147,7 +147,6 @@
         public int mAttrs;
         public int mNumParams;
         public boolean mSynthetic;
-        public boolean mIsLambda;
         public boolean mIsConstructor;
         public boolean mIsClinit;
         public boolean mIsBridge;
@@ -166,7 +165,6 @@
             mIsClinit = mName.equals("<clinit>");
             prefix = cname + "." + mName + "() - ";
             mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE);
-            mIsLambda = mSynthetic && mName.startsWith("lambda$");
 
             if (mIsClinit) {
                 sb = new StringBuilder(); // Discard output
@@ -227,7 +225,7 @@
 
             // IMPL: Whether MethodParameters attributes will be generated
             // for some synthetics is unresolved. For now, assume no.
-            if (mSynthetic && !mIsLambda) {
+            if (mSynthetic) {
                 warn(prefix + "synthetic has MethodParameter attribute");
             }
 
@@ -351,12 +349,10 @@
             } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
                 expect = "name";
                 allowMandated = true;
-            } else if (mIsBridge || mIsLambda) {
+            } else if (mIsBridge) {
                 allowSynthetic = true;
                 /*  you can't expect an special name for bridges' parameters.
-                 *  The name of the original parameters are now copied. Likewise
-                 *  for a method encoding the lambda expression, names are derived
-                 *  from source lambda's parameters and captured enclosing locals.
+                 *  The name of the original parameters are now copied.
                  */
                 expect = null;
             }
diff --git a/langtools/test/tools/javac/MethodParameters/LambdaTest.java b/langtools/test/tools/javac/MethodParameters/LambdaTest.java
index f84f90c..b79ca5e 100644
--- a/langtools/test/tools/javac/MethodParameters/LambdaTest.java
+++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8006582 8037546
+ * @bug 8006582 8037546 8138729
  * @summary javac should generate method parameters correctly.
  * @modules jdk.jdeps/com.sun.tools.classfile
  * @build Tester
@@ -32,8 +32,8 @@
  */
 
 /**
- * Post https://bugs.openjdk.java.net/browse/JDK-8037546, this test verifies
- * that MethodParameters attribute for lambdas are emitted properly.
+ * Post https://bugs.openjdk.java.net/browse/JDK-8138729, this test verifies
+ * that MethodParameters attribute are NOT emitted for lambdas.
  */
 class LambdaTest {
 
diff --git a/langtools/test/tools/javac/MethodParameters/LambdaTest.out b/langtools/test/tools/javac/MethodParameters/LambdaTest.out
index d836793..da662e1 100644
--- a/langtools/test/tools/javac/MethodParameters/LambdaTest.out
+++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.out
@@ -1,7 +1,7 @@
 class LambdaTest -- 
 LambdaTest.<init>()
 LambdaTest.foo(i)
-LambdaTest.lambda$static$1(x1/*synthetic*/)/*synthetic*/
-LambdaTest.lambda$null$0(final x1/*synthetic*/, x2/*synthetic*/)/*synthetic*/
+LambdaTest.lambda$static$1(arg0)/*synthetic*/
+LambdaTest.lambda$null$0(arg0, arg1)/*synthetic*/
 static interface LambdaTest$I -- inner
 LambdaTest$I.m(x)
diff --git a/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java
index 9441b21..8979f20 100644
--- a/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java
+++ b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -277,7 +277,7 @@
                     param = "final " + param;
                 }
                 sb.append(sep).append(param);
-                if (!m.isBridge() && !m.getName().startsWith("lambda$") && !expect.equals(param)) {
+                if (!m.isBridge() && !expect.equals(param)) {
                     error(prefix + "param[" + i + "]='"
                           + param + "' expected '" + expect + "'");
                     break;
diff --git a/langtools/test/tools/javac/NameClash/NameClashTest.java b/langtools/test/tools/javac/NameClash/NameClashTest.java
new file mode 100644
index 0000000..c3e9506
--- /dev/null
+++ b/langtools/test/tools/javac/NameClash/NameClashTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * 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 8074803
+ * @summary Incorrect name clash error
+ *
+ * @compile NameClashTest.java
+ */
+
+public class NameClashTest {
+
+    String log = "";
+
+    interface A1 {
+        A1 m(String s);
+    }
+
+    abstract class A2 implements A1 {
+        public abstract A2 m(String s);
+    }
+
+    interface B1 {
+        A1 m(String s);
+    }
+
+    interface B2 extends B1 {
+        A2 m(String s);
+    }
+
+    abstract class C extends A2 implements B2 {}
+
+    class D extends C {
+
+        public A2 m(String s) {
+            log += s;
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        NameClashTest nct = new NameClashTest();
+        A1 a1 = nct.new D();
+        a1.m("A1.m ");
+        A2 a2 = nct.new D();
+        a2.m("A2.m ");
+        B1 b1 = nct.new D();
+        b1.m("B1.m ");
+        B2 b2 = nct.new D();
+        b2.m("B2.m ");
+        C c = nct.new D();
+        c.m("C.m ");
+        D d = nct.new D();
+        d.m("D.m ");
+        if (!nct.log.equals("A1.m A2.m B1.m B2.m C.m D.m "))
+            throw new AssertionError("unexpected output: " + nct.log);
+    }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AllLocations.java b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AllLocations.java
index cddfe08..ed66750 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AllLocations.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AllLocations.java
@@ -25,7 +25,6 @@
  * @test
  * @bug 8027262
  * @summary Stress test for type annotatons
- * @ignore 8057685 javac should not crash compiling type annotations
  * @compile AllLocations.java
  */
 
diff --git a/langtools/test/tools/javac/doctree/DocCommentTester.java b/langtools/test/tools/javac/doctree/DocCommentTester.java
index 8a6775a..df8e57c 100644
--- a/langtools/test/tools/javac/doctree/DocCommentTester.java
+++ b/langtools/test/tools/javac/doctree/DocCommentTester.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -258,7 +258,6 @@
                     } catch (IOException e) {
                         source = "";
                     }
-
                     // remove existing gold by removing all block comments after the first '{'.
                     int start = source.indexOf("{");
                     while ((start = source.indexOf("\n/*\n", start)) != -1) {
@@ -663,8 +662,6 @@
                 else
                     return s;
             }
-
-
         }
     }
 
@@ -763,17 +760,15 @@
          * Normalize white space in places where the tree does not preserve it.
          */
         String normalize(String s) {
-            return s.trim()
-                    .replaceFirst("\\.\\s++([^@])", ". $1")
+            s = s.trim()
                     .replaceFirst("\\.\\s*\\n *@", ".\n@")
-                    .replaceFirst("\\s+<(/?p|pre|h[1-6])>", " <$1>")
                     .replaceAll("\\{@docRoot\\s+\\}", "{@docRoot}")
                     .replaceAll("\\{@inheritDoc\\s+\\}", "{@inheritDoc}")
                     .replaceAll("(\\{@value\\s+[^}]+)\\s+(\\})", "$1$2")
-                    .replaceAll("\n[ \t]+@", "\n@");
+                    .replaceAll("\n[ \t]+@", "\n@")
+                    .replaceAll("(\\{@code)(\\x20)(\\s+.*)", "$1$3");
+            return s;
         }
-
     }
-
 }
 
diff --git a/langtools/test/tools/javac/doctree/ElementTest.java b/langtools/test/tools/javac/doctree/ElementTest.java
index 244c56f..7951b2b 100644
--- a/langtools/test/tools/javac/doctree/ElementTest.java
+++ b/langtools/test/tools/javac/doctree/ElementTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7021614
+ * @bug 7021614 8078320
  * @summary extend com.sun.source API to support parsing javadoc comments
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
@@ -40,13 +40,13 @@
     void simple() { }
 /*
 DocComment[DOC_COMMENT, pos:1
-  firstSentence: empty
-  body: 3
+  firstSentence: 2
     StartElement[START_ELEMENT, pos:1
       name:p
       attributes: empty
     ]
     Text[TEXT, pos:4, para]
+  body: 1
     EndElement[END_ELEMENT, pos:8, p]
   block tags: empty
 ]
diff --git a/langtools/test/tools/javac/doctree/FirstSentenceTest.java b/langtools/test/tools/javac/doctree/FirstSentenceTest.java
index 82a29a2..6e803b2 100644
--- a/langtools/test/tools/javac/doctree/FirstSentenceTest.java
+++ b/langtools/test/tools/javac/doctree/FirstSentenceTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7021614
+ * @bug 7021614 8078320
  * @summary extend com.sun.source API to support parsing javadoc comments
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
@@ -117,6 +117,26 @@
 */
 
     /**
+     *
+     * <p>abc def ghi.
+     * jdl mno pqf
+     */
+    void newline_p() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+  firstSentence: 2
+    StartElement[START_ELEMENT, pos:2
+      name:p
+      attributes: empty
+    ]
+    Text[TEXT, pos:5, abc_def_ghi.]
+  body: 1
+    Text[TEXT, pos:19, jdl_mno_pqf]
+  block tags: empty
+]
+*/
+
+    /**
      * abc def ghi
      * </p>jkl mno pqr
      */
@@ -197,6 +217,40 @@
     ]
 ]
 */
-
+    /**
+     * <p> abc def.
+     * ghi jkl
+     */
+    void p_at_zero() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 2
+    StartElement[START_ELEMENT, pos:1
+      name:p
+      attributes: empty
+    ]
+    Text[TEXT, pos:4, _abc_def.]
+  body: 1
+    Text[TEXT, pos:15, ghi_jkl]
+  block tags: empty
+]
+*/
+    /**
+     * abc <p> def. ghi jkl
+     */
+    void p_at_nonzero() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 1
+    Text[TEXT, pos:1, abc]
+  body: 2
+    StartElement[START_ELEMENT, pos:5
+      name:p
+      attributes: empty
+    ]
+    Text[TEXT, pos:8, _def._ghi_jkl]
+  block tags: empty
+]
+*/
 }
 
diff --git a/langtools/test/tools/javac/doctree/InPreTest.java b/langtools/test/tools/javac/doctree/InPreTest.java
new file mode 100644
index 0000000..78730a4
--- /dev/null
+++ b/langtools/test/tools/javac/doctree/InPreTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 8078320
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.file
+ *          jdk.compiler/com.sun.tools.javac.tree
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @build DocCommentTester
+ * @run main DocCommentTester InPreTest.java
+ */
+
+class InPreTest {
+    /**
+     * xyz<pre> pqr </pre> abc{@code  def  }ghi
+     */
+    public void after_pre() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 1
+    Text[TEXT, pos:1, xyz]
+  body: 6
+    StartElement[START_ELEMENT, pos:4
+      name:pre
+      attributes: empty
+    ]
+    Text[TEXT, pos:9, _pqr_]
+    EndElement[END_ELEMENT, pos:14, pre]
+    Text[TEXT, pos:20, _abc]
+    Literal[CODE, pos:24, _def__]
+    Text[TEXT, pos:38, ghi]
+  block tags: empty
+]
+*/
+    /**
+     * abc{@code def}ghi
+     */
+    public void no_pre() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 3
+    Text[TEXT, pos:1, abc]
+    Literal[CODE, pos:4, def]
+    Text[TEXT, pos:15, ghi]
+  body: empty
+  block tags: empty
+]
+*/
+    /**
+     * xyz<pre> abc{@code  def  }ghi</pre>
+     */
+    public void pre_after_text() {}
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 1
+    Text[TEXT, pos:1, xyz]
+  body: 5
+    StartElement[START_ELEMENT, pos:4
+      name:pre
+      attributes: empty
+    ]
+    Text[TEXT, pos:9, _abc]
+    Literal[CODE, pos:13, _def__]
+    Text[TEXT, pos:27, ghi]
+    EndElement[END_ELEMENT, pos:30, pre]
+  block tags: empty
+]
+*/
+
+    /**
+     * abc{@code  def  }ghi
+     */
+    public void no_pre_extra_whitespace() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 3
+    Text[TEXT, pos:1, abc]
+    Literal[CODE, pos:4, _def__]
+    Text[TEXT, pos:18, ghi]
+  body: empty
+  block tags: empty
+]
+*/
+    /**
+     * <pre> abc{@code  def  }ghi</pre>
+     */
+    public void in_pre() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 4
+    StartElement[START_ELEMENT, pos:1
+      name:pre
+      attributes: empty
+    ]
+    Text[TEXT, pos:6, _abc]
+    Literal[CODE, pos:10, _def__]
+    Text[TEXT, pos:24, ghi]
+  body: 1
+    EndElement[END_ELEMENT, pos:27, pre]
+  block tags: empty
+]
+*/
+    /**
+     * <pre> abc{@code
+     * def  }ghi</pre>
+     */
+    public void in_pre_with_space_nl() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 4
+    StartElement[START_ELEMENT, pos:1
+      name:pre
+      attributes: empty
+    ]
+    Text[TEXT, pos:6, _abc]
+    Literal[CODE, pos:10, |_def__]
+    Text[TEXT, pos:24, ghi]
+  body: 1
+    EndElement[END_ELEMENT, pos:27, pre]
+  block tags: empty
+]
+*/
+
+    /**
+     * <pre> abc{@code
+     *def  }ghi</pre>
+     */
+    public void in_pre_with_nl() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 4
+    StartElement[START_ELEMENT, pos:1
+      name:pre
+      attributes: empty
+    ]
+    Text[TEXT, pos:6, _abc]
+    Literal[CODE, pos:10, |def__]
+    Text[TEXT, pos:23, ghi]
+  body: 1
+    EndElement[END_ELEMENT, pos:26, pre]
+  block tags: empty
+]
+*/
+    /**
+     * abc {@code
+     */
+    public void bad_code_no_content() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 2
+    Text[TEXT, pos:1, abc_]
+    Erroneous[ERRONEOUS, pos:5
+      code: compiler.err.dc.unterminated.inline.tag
+      body: {@code
+    ]
+  body: empty
+  block tags: empty
+]
+*/
+    /**
+     * abc {@code abc
+     */
+    public void bad_code_content() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: 2
+    Text[TEXT, pos:1, abc_]
+    Erroneous[ERRONEOUS, pos:5
+      code: compiler.err.dc.unterminated.inline.tag
+      body: {@code_abc
+    ]
+  body: empty
+  block tags: empty
+]
+*/
+}
diff --git a/langtools/test/tools/javac/doctree/TagTest.java b/langtools/test/tools/javac/doctree/TagTest.java
index 6168ee8..f23a9d6 100644
--- a/langtools/test/tools/javac/doctree/TagTest.java
+++ b/langtools/test/tools/javac/doctree/TagTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7021614
+ * @bug 7021614 8078320
  * @summary extend com.sun.source API to support parsing javadoc comments
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
@@ -35,6 +35,40 @@
 
 class TagTest {
     /**
+     * @tag:colon abc
+     */
+    void custom_tag_with_a_colon() {}
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: empty
+  body: empty
+  block tags: 1
+    UnknownBlockTag[UNKNOWN_BLOCK_TAG, pos:1
+      tag:tag:colon
+      content: 1
+        Text[TEXT, pos:12, abc]
+    ]
+]
+*/
+
+    /**
+     * @tag-hyphen abc
+     */
+    void custom_tag_with_a_hyphen() {}
+/*
+DocComment[DOC_COMMENT, pos:1
+  firstSentence: empty
+  body: empty
+  block tags: 1
+    UnknownBlockTag[UNKNOWN_BLOCK_TAG, pos:1
+      tag:tag-hyphen
+      content: 1
+        Text[TEXT, pos:13, abc]
+    ]
+]
+*/
+
+    /**
      * @author jjg
      */
     void simple_standard_block() { }
diff --git a/langtools/test/tools/javac/importscope/dependencies/DependenciesTest.java b/langtools/test/tools/javac/importscope/dependencies/DependenciesTest.java
index f0598eb..b4fc91d 100644
--- a/langtools/test/tools/javac/importscope/dependencies/DependenciesTest.java
+++ b/langtools/test/tools/javac/importscope/dependencies/DependenciesTest.java
@@ -194,11 +194,6 @@
         }
 
         @Override
-        public void push(AttributionKind ak, JCTree t) {
-            inProcess.push(null);
-        }
-
-        @Override
         public void pop() {
             inProcess.pop();
         }
diff --git a/langtools/test/tools/javac/lambda/MethodReference74.java b/langtools/test/tools/javac/lambda/MethodReference74.java
new file mode 100644
index 0000000..27cb86c
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/MethodReference74.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 8139836
+ * @summary Can't use super::x method reference when x is protected
+ * @run main MethodReference74
+ */
+
+public class MethodReference74 extends pkg.Parent {
+
+    public void protectedMethod() {
+        log = "In child, calling ... ";
+        Runnable r = super::protectedMethod;
+        r.run();
+        run(super::protectedMethod); // test also in invocation context.
+    }
+
+    private void run(Runnable r) {
+        r.run();
+    }
+
+    public static void main(String[] args) {
+        MethodReference74 child = new MethodReference74();
+        child.protectedMethod();
+        if (!child.log.equals("In child, calling ...  parent's  parent's ")) {
+            throw new AssertionError("Unexpected output" + child.log);
+        }
+    }
+}
diff --git a/langtools/test/tools/javac/lambda/pkg/Parent.java b/langtools/test/tools/javac/lambda/pkg/Parent.java
new file mode 100644
index 0000000..1cf6c20
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/pkg/Parent.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+package pkg;
+
+public class Parent {
+
+    public String log;
+
+    protected void protectedMethod() {
+        log += " parent's ";
+    }
+}
diff --git a/langtools/test/tools/javac/linenumbers/FinallyLineNumberTest.java b/langtools/test/tools/javac/linenumbers/FinallyLineNumberTest.java
new file mode 100644
index 0000000..892d365
--- /dev/null
+++ b/langtools/test/tools/javac/linenumbers/FinallyLineNumberTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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 8134759
+ * @summary Add LineNumberTable attribute for return bytecodes split around finally code
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ */
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute.Entry;
+
+import java.io.File;
+import java.io.IOException;
+
+public class FinallyLineNumberTest {
+    public static void main(String[] args) throws Exception {
+        // check that we have 5 consecutive entries for method()
+        Entry[] lines = findEntries();
+        if (lines == null) {
+            throw new Exception("finally line number table could not be loaded");
+        }
+        if (lines.length != 4) {
+            // Help debug
+            System.err.println("LineTable error, got lines:");
+            for (Entry e : lines) {
+                System.err.println(e.line_number);
+            }
+            throw new Exception("finally line number table incorrect: length=" + lines.length + " expected length=4");
+        }
+
+        // return null line, for the load null operation
+        int current = lines[0].line_number;
+        int first = current;
+
+        // finally line
+        current = lines[1].line_number;
+        if (current != first + 2) {
+            throw new Exception("finally line number table incorrect: got=" + current + " expected=" + (first + 2));
+        }
+
+        // return null line, for the return operation
+        current = lines[2].line_number;
+        if (current != first) {
+            throw new Exception("finally line number table incorrect: got=" + current + " expected=" + first);
+        }
+
+        // finally line, for when exception is thrown
+        current = lines[3].line_number;
+        if (current != first + 2) {
+            throw new Exception("finally line number table incorrect: got=" + current + " expected=" + (first + 2));
+        }
+    }
+
+    static Entry[] findEntries() throws IOException, ConstantPoolException {
+        ClassFile self = ClassFile.read(FinallyLineNumberTest.class.getResourceAsStream("FinallyLineNumberTest.class"));
+        for (Method m : self.methods) {
+            if ("method".equals(m.getName(self.constant_pool))) {
+                Code_attribute code_attribute = (Code_attribute)m.attributes.get(Attribute.Code);
+                for (Attribute at : code_attribute.attributes) {
+                    if (Attribute.LineNumberTable.equals(at.getName(self.constant_pool))) {
+                        return ((LineNumberTable_attribute)at).line_number_table;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    // This method should get LineNumberTable entries for:
+    // *) The load of the null
+    // *) The finally code for when an exception is *not* thrown
+    // *) The actual return, which should have the same line as the load of the null
+    // *) The finally code for when an exception *is* thrown, should have the same line as above finally code
+    public static String method(int field) {
+        try {
+            return null;
+        } finally {
+            field+=1; // Dummy
+        }
+    }
+}
diff --git a/langtools/test/tools/javac/parser/StringFoldingTest.java b/langtools/test/tools/javac/parser/StringFoldingTest.java
index 67ffff9..df0357a 100644
--- a/langtools/test/tools/javac/parser/StringFoldingTest.java
+++ b/langtools/test/tools/javac/parser/StringFoldingTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7068902
+ * @bug 7068902 8139751
  * @summary verify that string folding can be enabled or disabled
  * @modules jdk.compiler
  */
@@ -86,11 +86,14 @@
 
         if (disableStringFolding) {
             if (text.contains("FOLDED")) {
-                throw new AssertionError("Expected string folding");
+                throw new AssertionError("Expected no string folding");
+            }
+            if (!text.contains("\"F\"")) {
+                throw new AssertionError("Expected content not found");
             }
         } else {
             if (!text.contains("FOLDED")) {
-                throw new AssertionError("Expected no string folding");
+                throw new AssertionError("Expected string folding");
             }
         }
     }
