changeset 867:f44ec6545b9a

Merge
author attila
date Wed, 28 May 2014 16:53:43 +0200
parents 403fa5685a2f 185501198f64
children aeccdbb8d366
files buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java make/build.xml make/project.properties src/jdk/internal/dynalink/beans/BeanLinker.java src/jdk/nashorn/api/scripting/NashornScriptEngine.java src/jdk/nashorn/internal/codegen/CodeGenerator.java src/jdk/nashorn/internal/codegen/CompilationPhase.java src/jdk/nashorn/internal/codegen/CompileUnit.java src/jdk/nashorn/internal/codegen/Compiler.java src/jdk/nashorn/internal/codegen/ConstantData.java src/jdk/nashorn/internal/codegen/FindScopeDepths.java src/jdk/nashorn/internal/codegen/MapCreator.java src/jdk/nashorn/internal/ir/BinaryNode.java src/jdk/nashorn/internal/ir/debug/JSONWriter.java src/jdk/nashorn/internal/lookup/Lookup.java src/jdk/nashorn/internal/objects/ArrayBufferView.java src/jdk/nashorn/internal/objects/Global.java src/jdk/nashorn/internal/objects/NativeArray.java src/jdk/nashorn/internal/objects/NativeArrayBuffer.java src/jdk/nashorn/internal/objects/NativeDataView.java src/jdk/nashorn/internal/objects/NativeDebug.java src/jdk/nashorn/internal/objects/NativeError.java src/jdk/nashorn/internal/objects/NativeFloat32Array.java src/jdk/nashorn/internal/objects/NativeFloat64Array.java src/jdk/nashorn/internal/objects/NativeFunction.java src/jdk/nashorn/internal/objects/NativeInt16Array.java src/jdk/nashorn/internal/objects/NativeInt32Array.java src/jdk/nashorn/internal/objects/NativeInt8Array.java src/jdk/nashorn/internal/objects/NativeJSAdapter.java src/jdk/nashorn/internal/objects/NativeJavaImporter.java src/jdk/nashorn/internal/objects/NativeNumber.java src/jdk/nashorn/internal/objects/NativeObject.java src/jdk/nashorn/internal/objects/NativeRegExp.java src/jdk/nashorn/internal/objects/NativeString.java src/jdk/nashorn/internal/objects/NativeUint16Array.java src/jdk/nashorn/internal/objects/NativeUint32Array.java src/jdk/nashorn/internal/objects/NativeUint8Array.java src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java src/jdk/nashorn/internal/parser/Parser.java src/jdk/nashorn/internal/parser/TokenType.java src/jdk/nashorn/internal/runtime/AccessorProperty.java src/jdk/nashorn/internal/runtime/CodeInstaller.java src/jdk/nashorn/internal/runtime/Context.java src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java src/jdk/nashorn/internal/runtime/JSONFunctions.java src/jdk/nashorn/internal/runtime/JSType.java src/jdk/nashorn/internal/runtime/Property.java src/jdk/nashorn/internal/runtime/PropertyMap.java src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java src/jdk/nashorn/internal/runtime/ScriptEnvironment.java src/jdk/nashorn/internal/runtime/ScriptFunctionData.java src/jdk/nashorn/internal/runtime/ScriptObject.java src/jdk/nashorn/internal/runtime/Source.java src/jdk/nashorn/internal/runtime/SpillProperty.java src/jdk/nashorn/internal/runtime/UserAccessorProperty.java src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java src/jdk/nashorn/internal/runtime/resources/Options.properties src/jdk/nashorn/tools/Shell.java test/script/trusted/JDK-8006529.js test/script/trusted/event_queue.js test/script/trusted/optimistic_recompilation.js test/src/jdk/nashorn/internal/codegen/CompilerTest.java test/src/jdk/nashorn/internal/parser/ParserTest.java test/src/jdk/nashorn/internal/runtime/CodeStoreAndPathTest.java test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java
diffstat 173 files changed, 6148 insertions(+), 754 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed May 28 13:58:46 2014 +0200
+++ b/.hgtags	Wed May 28 16:53:43 2014 +0200
@@ -237,3 +237,13 @@
 65347535840f045f2cd4341d7466c51009b1b06f jdk9-b01
 b3517e51f40477f10db8bc30a557aa0ea712c274 jdk9-b02
 832f89ff25d903c45cfc994553f1ade8821a4398 jdk9-b03
+3f6ef92cd7823372c45e79125adba4cbf1c9f7b2 jdk9-b04
+2a1cac93c33317d828d4a5b81239204a9927cc4a jdk9-b05
+1f75bcbe74e315470dc0b75b7d5bcd209e287c39 jdk9-b06
+9a34d2a0a5bdaf0bf0d81d6fe6324aa0cfb35bfe jdk9-b07
+4764920fd81d631915b13ba03b5d962ab14a50c4 jdk9-b08
+27f6ea87dcbd52c4b59e34a9f18d5b3321d53fa7 jdk9-b09
+0eaa55c7abe5d96023a4b38a326f411209c43f49 jdk9-b10
+4d60c3292e14aac90dc3b8232496ba4af4254cc3 jdk9-b11
+282e9a675e079cc84dbfaa4c10050f08397faab0 jdk9-b12
+be4580ae56e2ef0ce521d3f840753eaa83cacf33 jdk9-b13
--- a/README	Wed May 28 13:58:46 2014 +0200
+++ b/README	Wed May 28 16:53:43 2014 +0200
@@ -81,13 +81,13 @@
     
 After that, you can run the tests using:
     cd make
-    ant test
+    ant clean test
     
 You can also run the ECMA-262 test suite with Nashorn. In order to do
 that, you will need to get a copy of it and put it in
 test/script/external/test262 directory. A convenient way to do it is:
 
-   hg clone http://hg.ecmascript.org/tests/test262/ test/script/external/test262
+   git clone https://github.com/tc39/test262 test/script/external/test262
     
 Alternatively, you can check it out elsewhere and make
 test/script/external/test262 a symbolic link to that directory. After
@@ -95,6 +95,11 @@
 
     cd nashorn~jdk8/nashorn/make
     ant test262
+
+Ant target to get/update external test suites:
+
+    ant externals
+    ant update-externals
     
 These tests take time, so we have a parallelized runner for them that
 takes advantage of all processor cores on the computer:
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Wed May 28 13:58:46 2014 +0200
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java	Wed May 28 16:53:43 2014 +0200
@@ -22,40 +22,62 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.nashorn.internal.tools.nasgen;
 
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_DESC;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC;
 
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.runtime.ScriptObject;
 
 /**
  * Details about a Java method or field annotated with any of the field/method
  * annotations from the jdk.nashorn.internal.objects.annotations package.
  */
 public final class MemberInfo implements Cloneable {
+    // class loader of this class
+    private static ClassLoader myLoader = MemberInfo.class.getClassLoader();
+
     /**
      * The different kinds of available class annotations
      */
     public static enum Kind {
-        /** This is a script class */
+
+        /**
+         * This is a script class
+         */
         SCRIPT_CLASS,
-        /** This is a constructor */
+        /**
+         * This is a constructor
+         */
         CONSTRUCTOR,
-        /** This is a function */
+        /**
+         * This is a function
+         */
         FUNCTION,
-        /** This is a getter */
+        /**
+         * This is a getter
+         */
         GETTER,
-        /** This is a setter */
+        /**
+         * This is a setter
+         */
         SETTER,
-        /** This is a property */
+        /**
+         * This is a property
+         */
         PROPERTY,
-        /** This is a specialized version of a function */
+        /**
+         * This is a specialized version of a function
+         */
         SPECIALIZED_FUNCTION,
-        /** This is a specialized version of a constructor */
+        /**
+         * This is a specialized version of a constructor
+         */
         SPECIALIZED_CONSTRUCTOR
     }
 
@@ -194,6 +216,7 @@
 
     /**
      * Check whether this MemberInfo is a getter that resides in the instance
+     *
      * @return true if instance setter
      */
     boolean isInstanceSetter() {
@@ -245,92 +268,200 @@
     }
 
     void verify() {
-        if (kind == Kind.CONSTRUCTOR) {
-            final Type returnType = Type.getReturnType(javaDesc);
-            if (! returnType.toString().equals(OBJECT_DESC)) {
-                error("return value should be of Object type, found " + returnType);
-            }
-            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
-            if (argTypes.length < 2) {
-                error("constructor methods should have at least 2 args");
-            }
-            if (! argTypes[0].equals(Type.BOOLEAN_TYPE)) {
-                error("first argument should be of boolean type, found " + argTypes[0]);
-            }
-            if (! argTypes[1].toString().equals(OBJECT_DESC)) {
-                error("second argument should be of Object type, found " + argTypes[0]);
-            }
+        switch (kind) {
+            case CONSTRUCTOR: {
+                final Type returnType = Type.getReturnType(javaDesc);
+                if (!isJSObjectType(returnType)) {
+                    error("return value of a @Constructor method should be of Object type, found " + returnType);
+                }
+                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+                if (argTypes.length < 2) {
+                    error("@Constructor methods should have at least 2 args");
+                }
+                if (!argTypes[0].equals(Type.BOOLEAN_TYPE)) {
+                    error("first argument of a @Constructor method should be of boolean type, found " + argTypes[0]);
+                }
+                if (!isJavaLangObject(argTypes[1])) {
+                    error("second argument of a @Constructor method should be of Object type, found " + argTypes[0]);
+                }
 
-            if (argTypes.length > 2) {
-                for (int i = 2; i < argTypes.length - 1; i++) {
-                    if (! argTypes[i].toString().equals(OBJECT_DESC)) {
-                        error(i + "'th argument should be of Object type, found " + argTypes[i]);
+                if (argTypes.length > 2) {
+                    for (int i = 2; i < argTypes.length - 1; i++) {
+                        if (!isJavaLangObject(argTypes[i])) {
+                            error(i + "'th argument of a @Constructor method should be of Object type, found " + argTypes[i]);
+                        }
+                    }
+
+                    final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
+                    final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
+                    if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
+                        error("last argument of a @Constructor method is neither Object nor Object[] type: " + lastArgTypeDesc);
+                    }
+
+                    if (isVarArg && argTypes.length > 3) {
+                        error("vararg of a @Constructor method has more than 3 arguments");
                     }
                 }
-
-                final String lastArgType = argTypes[argTypes.length - 1].toString();
-                final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC);
-                if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) {
-                    error("last argument is neither Object nor Object[] type: " + lastArgType);
+            }
+            break;
+            case SPECIALIZED_CONSTRUCTOR: {
+                final Type returnType = Type.getReturnType(javaDesc);
+                if (!isJSObjectType(returnType)) {
+                    error("return value of a @SpecializedConstructor method should be a valid JS type, found " + returnType);
+                }
+                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+                for (int i = 0; i < argTypes.length; i++) {
+                    if (!isValidJSType(argTypes[i])) {
+                        error(i + "'th argument of a @SpecializedConstructor method is not valid JS type, found " + argTypes[i]);
+                    }
+                }
+            }
+            break;
+            case FUNCTION: {
+                final Type returnType = Type.getReturnType(javaDesc);
+                if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) {
+                    error("return value of a @Function method should be a valid JS type, found " + returnType);
+                }
+                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+                if (argTypes.length < 1) {
+                    error("@Function methods should have at least 1 arg");
+                }
+                if (!isJavaLangObject(argTypes[0])) {
+                    error("first argument of a @Function method should be of Object type, found " + argTypes[0]);
                 }
 
-                if (isVarArg && argTypes.length > 3) {
-                    error("vararg constructor has more than 3 arguments");
+                if (argTypes.length > 1) {
+                    for (int i = 1; i < argTypes.length - 1; i++) {
+                        if (!isJavaLangObject(argTypes[i])) {
+                            error(i + "'th argument of a @Function method should be of Object type, found " + argTypes[i]);
+                        }
+                    }
+
+                    final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
+                    final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
+                    if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
+                        error("last argument of a @Function method is neither Object nor Object[] type: " + lastArgTypeDesc);
+                    }
+
+                    if (isVarArg && argTypes.length > 2) {
+                        error("vararg @Function method has more than 2 arguments");
+                    }
                 }
             }
-        } else if (kind == Kind.FUNCTION) {
-            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
-            if (argTypes.length < 1) {
-                error("function methods should have at least 1 arg");
-            }
-            if (! argTypes[0].toString().equals(OBJECT_DESC)) {
-                error("first argument should be of Object type, found " + argTypes[0]);
-            }
-
-            if (argTypes.length > 1) {
-                for (int i = 1; i < argTypes.length - 1; i++) {
-                    if (! argTypes[i].toString().equals(OBJECT_DESC)) {
-                        error(i + "'th argument should be of Object type, found " + argTypes[i]);
+            break;
+            case SPECIALIZED_FUNCTION: {
+                final Type returnType = Type.getReturnType(javaDesc);
+                if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) {
+                    error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType);
+                }
+                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+                for (int i = 0; i < argTypes.length; i++) {
+                    if (!isValidJSType(argTypes[i])) {
+                        error(i + "'th argument of a @SpecializedFunction method is not valid JS type, found " + argTypes[i]);
                     }
                 }
-
-                final String lastArgType = argTypes[argTypes.length - 1].toString();
-                final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC);
-                if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) {
-                    error("last argument is neither Object nor Object[] type: " + lastArgType);
+            }
+            break;
+            case GETTER: {
+                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+                if (argTypes.length != 1) {
+                    error("@Getter methods should have one argument");
+                }
+                if (!isJavaLangObject(argTypes[0])) {
+                    error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]);
                 }
 
-                if (isVarArg && argTypes.length > 2) {
-                    error("vararg function has more than 2 arguments");
+                if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) {
+                    error("return type of getter should not be void");
                 }
             }
-        } else if (kind == Kind.GETTER) {
-            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
-            if (argTypes.length != 1) {
-                error("getter methods should have one argument");
+            break;
+            case SETTER: {
+                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
+                if (argTypes.length != 2) {
+                    error("@Setter methods should have two arguments");
+                }
+                if (!isJavaLangObject(argTypes[0])) {
+                    error("first argument of a @Setter method should be of Object type, found: " + argTypes[0]);
+                }
+                if (!Type.getReturnType(javaDesc).toString().equals("V")) {
+                    error("return type of of a @Setter method should be void, found: " + Type.getReturnType(javaDesc));
+                }
             }
-            if (! argTypes[0].toString().equals(OBJECT_DESC)) {
-                error("first argument of getter should be of Object type, found: " + argTypes[0]);
-            }
-            if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) {
-                error("return type of getter should not be void");
-            }
-        } else if (kind == Kind.SETTER) {
-            final Type[] argTypes = Type.getArgumentTypes(javaDesc);
-            if (argTypes.length != 2) {
-                error("setter methods should have two arguments");
-            }
-            if (! argTypes[0].toString().equals(OBJECT_DESC)) {
-                error("first argument of setter should be of Object type, found: " + argTypes[0]);
-            }
-            if (!Type.getReturnType(javaDesc).toString().equals("V")) {
-                error("return type of setter should be void, found: " + Type.getReturnType(javaDesc));
+            break;
+            case PROPERTY: {
+                if (where == Where.CONSTRUCTOR) {
+                    if (isStatic()) {
+                        if (!isFinal()) {
+                            error("static Where.CONSTRUCTOR @Property should be final");
+                        }
+
+                        if (!isJSPrimitiveType(Type.getType(javaDesc))) {
+                            error("static Where.CONSTRUCTOR @Property should be a JS primitive");
+                        }
+                    }
+                } else if (where == Where.PROTOTYPE) {
+                    if (isStatic()) {
+                        if (!isFinal()) {
+                            error("static Where.PROTOTYPE @Property should be final");
+                        }
+
+                        if (!isJSPrimitiveType(Type.getType(javaDesc))) {
+                            error("static Where.PROTOTYPE @Property should be a JS primitive");
+                        }
+                    }
+                }
             }
         }
     }
 
+    private static boolean isValidJSType(final Type type) {
+        return isJSPrimitiveType(type) || isJSObjectType(type);
+    }
+
+    private static boolean isJSPrimitiveType(final Type type) {
+        switch (type.getSort()) {
+            case Type.BOOLEAN:
+            case Type.INT:
+            case Type.LONG:
+            case Type.DOUBLE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static boolean isJSObjectType(final Type type) {
+        return isJavaLangObject(type) || isJavaLangString(type) || isScriptObject(type);
+    }
+
+    private static boolean isJavaLangObject(final Type type) {
+        return type.getDescriptor().equals(OBJECT_DESC);
+    }
+
+    private static boolean isJavaLangString(final Type type) {
+        return type.getDescriptor().equals(STRING_DESC);
+    }
+
+    private static boolean isScriptObject(final Type type) {
+        if (type.getDescriptor().equals(SCRIPTOBJECT_DESC)) {
+            return true;
+        }
+
+        if (type.getSort() == Type.OBJECT) {
+            try {
+                final Class clazz = Class.forName(type.getClassName(), false, myLoader);
+                return ScriptObject.class.isAssignableFrom(clazz);
+            } catch (final ClassNotFoundException cnfe) {
+                return false;
+            }
+        }
+
+        return false;
+    }
+
     private void error(final String msg) {
-        throw new RuntimeException(javaName + javaDesc + " : " + msg);
+        throw new RuntimeException(javaName + " of type " + javaDesc + " : " + msg);
     }
 
     /**
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Wed May 28 13:58:46 2014 +0200
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Wed May 28 16:53:43 2014 +0200
@@ -60,6 +60,8 @@
     static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
     static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
     static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
+    static final String STRING_TYPE = TYPE_STRING.getInternalName();
+    static final String STRING_DESC = TYPE_STRING.getDescriptor();
     static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
     static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName();
     static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName();
@@ -128,6 +130,7 @@
 
     // ScriptObject
     static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
+    static final String SCRIPTOBJECT_DESC = TYPE_SCRIPTOBJECT.getDescriptor();
     static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
 
     static final String GETTER_PREFIX = "G$";
--- a/make/build.xml	Wed May 28 13:58:46 2014 +0200
+++ b/make/build.xml	Wed May 28 16:53:43 2014 +0200
@@ -42,6 +42,9 @@
     <condition property="hg.executable" value="/usr/local/bin/hg" else="hg">
       <available file="/usr/local/bin/hg"/>
     </condition>
+    <condition property="git.executable" value="/usr/local/bin/git" else="git">
+      <available file="/usr/local/bin/git"/>
+    </condition>
     <!-- check if JDK already has ASM classes -->
     <available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/>
     <!-- check if testng.jar is avaiable -->
@@ -355,8 +358,30 @@
       <include name="**/runtime/regexp/*Test.class"/>
       <include name="**/runtime/regexp/joni/*Test.class"/>
       <include name="**/framework/*Test.class"/>
+      <exclude name="jdk/nashorn/internal/runtime/CodeStoreAndPathTest.class"/>
     </fileset>
 
+    <fileset id="test.nosecurity.classes" dir="${build.test.classes.dir}">
+      <include name="**/framework/ScriptTest.class"/>
+    </fileset>
+
+    <fileset id="test.nooptimistic.classes" dir="${build.test.classes.dir}">
+      <include name="jdk/nashorn/internal/runtime/CodeStoreAndPathTest.class"/>
+    </fileset>
+
+    <testng outputdir="${build.nooptimistic.test.results.dir}" classfilesetref="test.nooptimistic.classes"
+       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
+      <sysproperty key="nashorn.optimistic" value="false"/>
+      <propertyset>
+        <propertyref prefix="nashorn."/>
+      </propertyset>
+      <classpath>
+          <pathelement path="${run.test.classpath}"/>
+      </classpath>
+    </testng>
+
     <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
        verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
       <jvmarg line="${ext.class.path}"/>
@@ -373,6 +398,22 @@
           <pathelement path="${run.test.classpath}"/>
       </classpath>
     </testng>
+
+    <testng outputdir="${build.nosecurity.test.results.dir}" classfilesetref="test.nosecurity.classes"
+       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
+      <propertyset>
+        <propertyref prefix="nashorn."/>
+      </propertyset>
+      <propertyset>
+        <propertyref prefix="test-sys-prop-no-security."/>
+        <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/>
+      </propertyset>
+      <classpath>
+          <pathelement path="${run.test.classpath}"/>
+      </classpath>
+    </testng>
   </target>
 
   <target name="check-jemmy.jfx.testng" unless="jemmy.jfx.testng.available">
@@ -515,18 +556,17 @@
 
   <!-- test262 test suite -->
   <target name="get-test262" depends="init" unless="${test-sys-prop.external.test262}">
-    <!-- clone test262 mercurial repo -->
-    <exec executable="${hg.executable}">
+    <!-- clone test262 git repo -->
+    <exec executable="${git.executable}">
        <arg value="clone"/>
-       <arg value="http://hg.ecmascript.org/tests/test262"/>
+       <arg value="https://github.com/tc39/test262"/>
        <arg value="${test.external.dir}/test262"/>
     </exec>
   </target>
   <target name="update-test262" depends="init" if="${test-sys-prop.external.test262}">
-    <!-- update test262 mercurial repo -->
-    <exec executable="${hg.executable}" dir="${test.external.dir}/test262">
+    <!-- update test262 git repo -->
+    <exec executable="${git.executable}" dir="${test.external.dir}/test262">
        <arg value="pull"/>
-       <arg value="-u"/>
     </exec>
   </target>
 
--- a/make/project.properties	Wed May 28 13:58:46 2014 +0200
+++ b/make/project.properties	Wed May 28 16:53:43 2014 +0200
@@ -60,6 +60,8 @@
 
 # test results directory
 build.test.results.dir=${build.dir}/test/reports
+build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports
+build.nooptimistic.test.results.dir=${build.dir}/test/nooptimistic/reports
 
 # This directory is removed when the project is cleaned:
 dist.dir=dist
@@ -114,6 +116,7 @@
 
 # test scripts to run
 test.dir=test
+test.nosecurity.dir=test/script/nosecurity
 test.script.dir=test/script
 test.basic.dir=test/script/basic
 test.maptests.dir=test/script/maptests
@@ -132,8 +135,12 @@
 test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
 test-sys-prop.test.basic.dir=${test.basic.dir}
 
+test-sys-prop-no-security.test.dir=${test.dir}
+test-sys-prop-no-security.test.js.roots=${test.nosecurity.dir}
+
 # framework root for our script tests
 test-sys-prop.test.js.framework=${test.script.dir}/assert.js
+test-sys-prop-no-security.test.js.framework=${test.script.dir}/assert.js
 
 # Control the verbosity of ParserTest
 test-sys-prop.parsertest.verbose=false
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/BufferArray.java	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import jdk.nashorn.api.scripting.AbstractJSObject;
+import java.nio.DoubleBuffer;
+
+/**
+ * Simple class demonstrating pluggable script object
+ * implementation. By implementing jdk.nashorn.api.scripting.JSObject
+ * (or extending AbstractJSObject which implements it), you
+ * can supply a friendly script object. Nashorn will call
+ * 'magic' methods on such a class on 'obj.foo, obj.foo = 33,
+ * obj.bar()' etc. from script.
+ *
+ * In this example, Java nio DoubleBuffer object is wrapped
+ * as a friendly script object that provides indexed acces
+ * to buffer content and also support array-like "length"
+ * readonly property to retrieve buffer's capacity. This class
+ * also demonstrates a function valued property called "buf".
+ * On 'buf' method, we return the underlying nio buffer object
+ * that is being wrapped.
+ */
+public class BufferArray extends AbstractJSObject {
+    // underlying nio buffer
+    private final DoubleBuffer buf;
+
+    public BufferArray(int size) {
+        buf = DoubleBuffer.allocate(size);
+    }
+
+    public BufferArray(DoubleBuffer buf) {
+        this.buf = buf;
+    }
+
+    // called to check if indexed property exists
+    @Override
+    public boolean hasSlot(int index) {
+        return index > 0 && index < buf.capacity();
+    }
+
+    // get the value from that index
+    @Override
+    public Object getSlot(int index) {
+       return buf.get(index);
+    }
+
+    // set the value at that index
+    @Override
+    public void setSlot(int index, Object value) {
+       buf.put(index, ((Number)value).doubleValue());
+    }
+
+    // do you have a property of that given name?
+    @Override
+    public boolean hasMember(String name) {
+       return "length".equals(name) || "buf".equals(name);
+    }
+
+    // get the value of that named property
+    @Override
+    public Object getMember(String name) {
+       switch (name) {
+          case "length":
+              return buf.capacity();
+          case "buf":
+              // return a 'function' value for this property
+              return new AbstractJSObject() {
+                  @Override
+                  public Object call(Object thiz, Object... args) {
+                      return BufferArray.this.buf;
+                  }
+
+                  // yes, I'm a function !
+                  @Override
+                  public boolean isFunction() {
+                      return true;
+                  }
+              };
+       }
+       return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/CastExample.java	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple java example with type casts.
+// see javacastcounter.js.
+
+class CastExample {
+   public final static int I = (int)23.33;
+   public final String str = (String)"hello";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/README	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,1 @@
+Simple Nashorn examples that can be run with "jjs" tool.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/array_mapreduce.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Usage: jjs array_mapreduce.js
+
+// Many Array.prototype functions such as map, 
+// filter, reduce, reduceRight, every, some are generic.
+// These functions accept ECMAScript array as well as 
+// many array-like objects including java arrays.
+// So, you can do map/filter/reduce with Java streams or
+// you can also use Array.prototype functions as below.
+// See also http://en.wikipedia.org/wiki/MapReduce
+
+var DoubleArray = Java.type("double[]");
+var StringArray = Java.type("java.lang.String[]");
+
+var map = Array.prototype.map;
+var filter = Array.prototype.filter;
+var reduce = Array.prototype.reduce;
+
+var jarr = new StringArray(5);
+jarr[0] = "nashorn";
+jarr[1] = "ecmascript";
+jarr[2] = "javascript";
+jarr[3] = "js";
+jarr[4] = "scheme";
+
+// sum of word lengths
+print("Sum word length:",
+    reduce.call(
+        map.call(jarr, function(x) x.length),
+        function(x, y) x + y)
+);
+
+// another array example involving numbers
+jarr = new DoubleArray(10);
+// make random array of numbers
+for (var i = 0; i < jarr.length; i++)
+    jarr[i] = Math.random();
+
+var forEach = Array.prototype.forEach;
+// print numbers in the array
+forEach.call(jarr, function(x) print(x));
+
+// print sum of squares of the random numbers
+print("Square sum:",
+    reduce.call(
+        map.call(jarr, function(x) x*x), 
+        function(x, y) x + y)
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/astviewer.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,98 @@
+#// Usage: jjs -scripting -fx astviewer.js -- <scriptfile>
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+if (!$OPTIONS._fx) {
+    print("Usage: jjs -scripting -fx astviewer.js -- <.js file>");
+    exit(1);
+}
+
+// Using JavaFX from Nashorn. See also:
+// http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/javafx.html
+
+// This example shows AST of a script file as a JavaFX
+// tree view in a window. If no file is specified, AST of
+// this script file is shown. This script demonstrates
+// 'load' function, JavaFX support by -fx, readFully function
+// in scripting mode.
+
+// JavaFX classes used
+var StackPane = Java.type("javafx.scene.layout.StackPane");
+var Scene     = Java.type("javafx.scene.Scene");
+var TreeItem  = Java.type("javafx.scene.control.TreeItem");
+var TreeView  = Java.type("javafx.scene.control.TreeView");
+
+// Create a javafx TreeItem to view a AST node
+function treeItemForASTNode(ast, name) {
+    var item = new TreeItem(name);
+    for (var prop in ast) {
+       var node = ast[prop];
+       if (typeof node == 'object') {
+           if (node == null) {
+               // skip nulls
+               continue;
+           }
+
+           if (Array.isArray(node) && node.length == 0) {
+               // skip empty arrays
+               continue;
+           }
+
+           var subitem = treeItemForASTNode(node, prop);
+       } else {
+           var subitem = new TreeItem(prop + ": " + node);
+       }
+       item.children.add(subitem);
+    }
+    return item;
+}
+
+// do we have a script file passed? if not, use current script
+var sourceName = arguments.length == 0? __FILE__ : arguments[0];
+
+// load parser.js from nashorn resources
+load("nashorn:parser.js");
+
+// read the full content of the file and parse it 
+// to get AST of the script specified
+var ast = parse(readFully(sourceName));
+
+// JavaFX start method
+function start(stage) {
+    stage.title = "AST Viewer";
+    var rootItem = treeItemForASTNode(ast, sourceName);
+    var tree = new TreeView(rootItem);
+    var root = new StackPane();
+    root.children.add(tree);
+    stage.scene = new Scene(root, 300, 450);
+    stage.show();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/barchart_weather.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,116 @@
+#// Usage: jjs -fx barchart_weather.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Example that retrieves weather data from a URL in JSON
+// format and draws bar chart using JavaFX
+
+// -fx check
+if (! $OPTIONS._fx) {
+    print("Usage: jjs -fx barchart_weather.js");
+    exit(1);
+}
+
+// Java classes used
+var URL = Java.type("java.net.URL");
+var BufferedReader = Java.type("java.io.BufferedReader");
+var InputStreamReader = Java.type("java.io.InputStreamReader");
+
+// function to retrieve text content of the given URL
+function readTextFromURL(url) {
+    var str = '';
+    var u = new URL(url);
+    var reader = new BufferedReader(
+        new InputStreamReader(u.openStream()));
+    try {
+        reader.lines().forEach(function(x) str += x);
+        return str;
+    } finally {
+        reader.close();
+    }
+}
+
+// change URL for your city here!
+var url = "http://api.openweathermap.org/data/2.5/forecast?q=chennai,india&units=metric&mode=json";
+
+// download JSON document and parse
+var json = readTextFromURL(url);
+var weather = JSON.parse(json);
+
+// View JSON of this using site such as http://www.jsoneditoronline.org/ to know
+// about the JSON data format used by this site
+
+// Extracted data from the json object
+var temp = weather.list.map(function(x) x.main.temp);
+var temp_min = weather.list.map(function(x) x.main.temp_min);
+var temp_max = weather.list.map(function(x) x.main.temp_max);
+var date = weather.list.map(function(x) x.dt_txt);
+
+// JavaFX classes used
+var Scene = Java.type("javafx.scene.Scene");
+var BarChart = Java.type("javafx.scene.chart.BarChart");
+var CategoryAxis = Java.type("javafx.scene.chart.CategoryAxis");
+var NumberAxis = Java.type("javafx.scene.chart.NumberAxis");
+var XYChart = Java.type("javafx.scene.chart.XYChart");
+
+function start(stage) {
+    stage.title="Chennai Weather Bar Chart";
+    var xAxis = new CategoryAxis();
+    xAxis.label = "date/time";
+    var yAxis = new NumberAxis();
+    yAxis.label = "temp in C";
+    var bc = new BarChart(xAxis, yAxis);
+
+    // 3 bars per datetime item - temp, min temp and max temp
+    var s1 = new XYChart.Series();
+    s1.name = "temp";
+    for (d in date) {
+        s1.data.add(new XYChart.Data(date[d], temp[d]));
+    }
+
+    var s2 = new XYChart.Series();
+    s2.name = "min temp";
+    for (d in date) {
+        s2.data.add(new XYChart.Data(date[d], temp_min[d]));
+    }
+
+    var s3 = new XYChart.Series();
+    s3.name = "max temp";
+    for (d in date) {
+        s3.data.add(new XYChart.Data(date[d], temp_max[d]));
+    }
+
+    bc.data.addAll(s1, s2, s3);
+
+    stage.scene = new Scene(bc, 800, 600);
+    stage.show();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/call_lambda.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn allows you treat every Java8 lambda as a function
+
+var JFunction = Java.type("java.util.function.Function");
+var obj = new JFunction() {
+    apply: function(x) {
+        print(x + ", lambda");
+    }
+};
+
+// prints 'function'
+print(typeof obj);
+
+// call it!
+obj("hello");
--- a/samples/counters.js	Wed May 28 13:58:46 2014 +0200
+++ b/samples/counters.js	Wed May 28 16:53:43 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -33,7 +33,11 @@
  * This file can be run along with any script you want to run
  * to print aggregate stat counters from nashorn.
  *
- * Usage:  jjs <your-file.js> counters.js
+ * Usage:  jjs -J-Dnashorn.debug <your-file.js> counters.js
  */
 
-Debug.dumpCounters();
+if (java.lang.System.getProperty("nashorn.debug") == null) {
+    print("Usage: jjs -J-Dnashorn.debug <your-file.js> counters.js");
+} else {
+    Debug.dumpCounters();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/dirname.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// __DIR__ variable is equivalent of `dirname $0` in
+// shell scripts - expands to the directory where
+// the current script is located.
+
+print("This script is in the directory: " + __DIR__);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/disassemble.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Usage: jjs disassemble.js -- <.class-file-path>
+
+// Simple .class disassembler that uses bundled ObjectWeb ASM
+// classes in jdk8. WARNING: Bundled ObjectWeb ASM classes are
+// not part of official jdk8 API. It can be changed/removed 
+// without notice. So, this script is brittle by design!
+
+// This example demonstrates passing arguments to script
+// from jjs command line, nio and ASM usage.
+
+// classes used
+var FileSystems = Java.type("java.nio.file.FileSystems");
+var Files = Java.type("java.nio.file.Files");
+var System = Java.type("java.lang.System");
+var PrintWriter = Java.type("java.io.PrintWriter");
+
+// WARNING: uses non-API classes of jdk8!
+var ClassReader = Java.type("jdk.internal.org.objectweb.asm.ClassReader");
+var TraceClassVisitor = Java.type("jdk.internal.org.objectweb.asm.util.TraceClassVisitor");
+
+// convert file name to Path instance
+function path(file) {
+    return FileSystems.default.getPath(file);
+}
+
+// read all file content as a byte[]
+function readAllBytes(file) {
+    return Files.readAllBytes(path(file));
+}
+
+// disassemble .class byte[] and prints output to stdout
+function disassemble(bytecode) {
+    var pw = new PrintWriter(System.out);
+    new ClassReader(bytecode).accept(new TraceClassVisitor(pw), 0);
+}
+
+// check for command line arg (for .class file name)
+if (arguments.length == 0 || !arguments[0].endsWith('.class')) {
+    print("Usage: jjs disassemble -- <.class file>");
+    exit(1);
+}
+
+// disassemble the given .class file
+disassemble(readAllBytes(arguments[0]));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/README	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,1 @@
+Using javax.script engine API of nashorn from script!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/accessvar.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple example showing global variable access from caller
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// eval code!
+engine.eval("x = 'hello'");
+
+// access global var from engine
+print(engine.get('x'));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/callfunc.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// simple example showing how to call a global script 
+// function from caller
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// eval code!
+engine.eval("function func(name) { print('I am func, hello ' + name) }");
+
+// invoke functions, methods of code evaluated by engine
+// from javax.script.Invocable interface. But, hey, 
+// calling code is JavaScript and don't worry about types :)
+
+engine.invokeFunction("func", "Nashorn");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/callmethod.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,64 @@
+#// Usage: jjs -scripting callmethod.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// simple example demonstrating calling a script object
+// method from script engine user code
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// eval code - too many script escapes?
+// use heredoc !
+engine.eval(<<CODE
+    var obj = {
+        func: function() {
+            print("I am func of " + this);
+        },
+
+        toString: function() {
+            return "Object 'obj'";
+        }
+   };
+CODE);
+
+// invoke methods of an object in script world
+// from javax.script.Invocable interface. But, hey, 
+// calling code is JavaScript and don't worry about types :)
+
+// get that script object on which to call a method
+var scriptObj = engine.get("obj");
+// call 'func' method on object 'obj'
+engine.invokeMethod(scriptObj, "func");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/exposevar.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Example showing how to expose a script global var from caller
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// expose variable to engine
+engine.put("name", "Nashorn");
+
+// access it from script
+engine.eval("print('Hello, ' + name)");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/foreignobject.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,71 @@
+#// Usage: jjs -scripting foreignobject.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// cross nashorn engine scripting
+// access script objects from other engines in natural syntax
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// eval code!
+engine.eval(<<CODE
+    var obj = {
+        foo: 42,
+        func: function() {
+            print("func: " + this.foo);
+        }
+    };
+CODE);
+
+// Nashorn engine returns script objects as instance of
+// the class jdk.nashorn.api.scripting.ScriptObjectMirror
+// But nashorn's dynalink linker can treat these objects
+// specially to support natural script syntax to access..
+// In Java code, you need to use ScriptObjectMirror's 
+// methods though. Once again, script world is simpler :-)
+
+var foreignObj = engine.get("obj");
+// access properties, functions of it
+// with natural syntax
+print(foreignObj.foo);
+foreignObj.func();
+print(typeof foreignObj.func);
+
+// access engine's global
+var foreignGlobal = engine.eval("this");
+// create objects in engine's world from here!
+print(new foreignGlobal.Object());
+print(new foreignGlobal.Date());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/hello.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple hello world example showing create engine
+// and eval simple script
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+// eval code!
+engine.eval("print('hello world')");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/interface.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,60 @@
+#// Usage: jjs -scripting interface.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Example demonstrating how to implement a Java interface
+// whose methods are backed by global script functions
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// eval code - too many script escapes?
+// use heredoc !
+engine.eval(<<CODE
+function run() {
+    print("run global function called");
+}
+CODE);
+
+// create Java interface object whose methods are
+// implemented by script functions. This is from
+// javax.script.Invocable. But we are in JS world, 
+// don't worry about types :)
+
+var Runnable = Java.type("java.lang.Runnable");
+var r = engine.getInterface(Runnable.class);
+print(r.class);
+
+r.run();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/interface2.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,63 @@
+#// Usage: jjs -scripting interface2.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple example demonstrating how to implement java interface
+// whose methods are backed by script methods of a script object
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// eval code - too many script escapes?
+// use heredoc !
+engine.eval(<<CODE
+  var obj = {
+    run: function() {
+        print("I am run method of 'obj'");
+    }
+  };
+CODE);
+
+// create Java interface object whose methods are
+// implemented by script methods of a script object
+// This is from javax.script.Invocable. But we are
+// in JS world, don't worry about types :)
+
+var Runnable = Java.type("java.lang.Runnable");
+
+var scriptObj = engine.get("obj");
+var r = engine.getInterface(scriptObj, Runnable.class);
+print(r.class);
+r.run();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/engine/lambda_as_func.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple example demonstrating how to expose 'function's
+// from embedding code. Any lambda object exposed to engine
+// can be called as 'function' in script.
+
+var ScriptEngineManager = Java.type("javax.script.ScriptEngineManager");
+// create manager
+var manager = new ScriptEngineManager();
+// create engine
+var engine = manager.getEngineByName("js");
+
+// Any lambda (@FunctionalInterface annotated type) object can be
+// be exposed from script embedding code. Script can call
+// it as a function
+engine.put("upper", new java.util.function.Function() {
+     apply: function(x) x.toUpperCase()
+});
+
+print(engine.eval("upper('hello')"));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/env.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,43 @@
+#// Usage: jjs -scripting env.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// In nashorn -scripting mode, 
+// "$ENV" object exposes process 
+// environment variables
+
+print($ENV.PATH);
+print($ENV.JAVA_HOME);
+
+for (i in $ENV) {
+   print(i, "->", $ENV[i]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/expression_closure.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn supports expression closures extension of
+// Mozilla JavaScript 1.8. See also
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/1.8
+
+// leave {, } and 'return' keyword
+
+function sqr(x) x*x;
+
+// prints 289 (= 17*17)
+print(sqr(17));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/fileline.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn supports pseudo global variables __FILE__
+// and __LINE__ that expands to currently executed
+// script file name and current script line number
+
+// prints current file and line number
+print("executing " + __FILE__ + " @ " + __LINE__);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/fizzbuzz.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// What is FizzBuzz? http://c2.com/cgi/wiki?FizzBuzzTest
+
+// Yet another FizzBuzz impl. using Java 8 lambda and stream
+// but using Nashorn. This is ECMAScript port of @stuartmarks'
+// Java implementation
+
+var IntStream = Java.type("java.util.stream.IntStream");
+
+function ifmod(m, r, f) {
+    return function(i) { return i % m == 0? r : f(i); }
+}
+
+// pass script function for lambda
+IntStream.rangeClosed(1, 100).
+   mapToObj(
+      ifmod(15, "FizzBuzz", ifmod(5, "Buzz", ifmod(3, "Fizz", String))))
+      .forEach(print);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/for_each.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn supports for..each extension supported
+// by Mozilla. See also
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for_each...in
+
+var strs = [ "hello", "world" ];
+for each (str in strs)
+    print(str);
+
+// create a java int[] object
+var JArray = Java.type("int[]");
+var arr = new JArray(10);
+
+// store squares as values
+for (i in arr) 
+    arr[i] = i*i;
+
+// for .. each on java arrays
+print("squares");
+for each (i in arr)
+    print(i);
+
+var System = Java.type("java.lang.System");
+
+// for..each on java Iterables
+// print System properties as name = value pairs
+print("System properties");
+for each (p in System.properties.entrySet()) {
+    print(p.key, "=", p.value);
+} 
+
+// print process environment vars as name = value pairs
+print("Process environment");
+for each (e in System.env.entrySet()) {
+    print(e.key, "=", e.value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/gaussian_random.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// print 100 Guassian distributed numbers
+
+var Random = Java.type("java.util.Random");
+var DoubleStream = Java.type("java.util.stream.DoubleStream");
+
+var r = new Random();
+
+// expression closure (see expression_closure.js as well)
+// passed as lambda double generator. "print" passed as 
+// double consumer lambda to 'forEach' method.
+
+DoubleStream
+    .generate(function() r.nextGaussian())
+    .limit(100)
+    .forEach(print);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/gaussian_random_bind.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// print 100 Guassian distributed numbers
+
+var Random = Java.type("java.util.Random");
+var DoubleStream = Java.type("java.util.stream.DoubleStream");
+
+// function as lambda double generator. "print" passed as 
+// double consumer lambda to 'forEach' method.
+// Function.prototype.bind used to attach 'state' for the
+// generator function.
+
+DoubleStream
+    .generate(
+         function(r) {
+             return r.nextGaussian()
+         }.bind(this, new Random()))
+    .limit(100)
+    .forEach(print);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/gutenberg.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,142 @@
+#// Usage: jjs -scripting gutenberg.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple example that demonstrates reading XML Rss feed
+// to generate a HTML file from script and show it by browser
+
+// Java classes used
+var Characters = Java.type("javax.xml.stream.events.Characters");
+var Factory = Java.type("javax.xml.stream.XMLInputFactory");
+var File = Java.type("java.io.File");
+var FileWriter = Java.type("java.io.FileWriter");
+var PrintWriter = Java.type("java.io.PrintWriter");
+var URL = Java.type("java.net.URL");
+
+// read Rss feed from a URL. Returns an array
+// of objects having only title and link properties
+function readRssFeed(url) {
+    var fac = Factory.newInstance();
+    var reader = fac.createXMLEventReader(url.openStream());
+
+    // get text content from next event
+    function getChars() {
+        var result = "";
+        var e = reader.nextEvent();
+        if (e instanceof Characters) {
+            result = e.getData();
+        }
+        return result;
+    }
+
+    var items = [];
+    var title, link;
+    var inItem = false;
+    while (reader.hasNext()) {
+        var evt = reader.nextEvent();
+        if (evt.isStartElement()) {
+            var local = evt.name.localPart;
+            if (local == "item") {
+               // capture title, description now
+               inItem = true;
+            }
+        
+            if (inItem) {
+                switch (local) {
+                    case 'title':
+                        title = getChars();
+                        break;
+                    case 'link':
+                        link = getChars();
+                        break;
+                }
+            }
+        } else if (evt.isEndElement()) {
+            var local = evt.name.localPart;
+            if (local == "item") {
+                // one item done, save it in result array
+                items.push({ title: title, link: link });
+                inItem = false;
+            }
+        }
+    }
+
+    return items;
+}
+
+// generate simple HTML for an RSS feed
+function getBooksHtml() {
+    var url = new URL("http://www.gutenberg.org/cache/epub/feeds/today.rss");
+    var items = readRssFeed(url);
+
+    var str = "<ul>";
+
+    // Nashorn's string interpolation and heredoc
+    // support is very handy in generating text content
+    // that is filled with elements from runtime objects.
+    // We insert title and link in <li> elements here.
+    for each (i in items) {
+        str += <<EOF
+<li>
+    <a href="${i.link}">${i.title}</a>
+</li>
+EOF
+    }
+    str += "</ul>";
+    return str;
+}
+
+// write the string to the given file
+function writeTo(file, str) {
+    var w = new PrintWriter(new FileWriter(file));
+    try {
+        w.print(str);
+    } finally {
+        w.close();
+    }
+}
+
+// generate books HTML
+var str = getBooksHtml();
+
+// write to file. __DIR__ is directory where
+// this script is stored.
+var file = new File(__DIR__ + "books.html");
+writeTo(file, str);
+
+// show it by desktop browser
+try {
+    var Desktop = Java.type("java.awt.Desktop");
+    Desktop.desktop.browse(file.toURI());
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/heredoc.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,51 @@
+#// Usage: jjs -scripting heredoc.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Nashorn supports Shell script like here-documents
+// in -scripting mode. Here-docs are multi-line strings
+// that are possibly interpolated with ${} expressions
+// See also http://en.wikipedia.org/wiki/Here_document
+
+var sender = "Buffy the Vampire Slayer";
+var recipient = "Spike";
+ 
+print(<<END
+ 
+Dear ${recipient},
+ 
+I wish you to leave Sunnydale and never return.
+ 
+Not Quite Love,
+${sender}
+ 
+END);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/interface_impl.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn supports Java interface implementation
+// by script using anonymous class-like syntax
+
+var Runnable = Java.type("java.lang.Runnable");
+var Thread = Java.type("java.lang.Thread");
+// use anonymous class-like new syntax
+var r = new Runnable() {
+    run: function() {
+        print("I am a runnable " + Thread.currentThread());
+    }
+}
+
+r.run();
+
+var t = new Thread(r);
+t.start();
+t.join();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/javaastviewer.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,202 @@
+#// Usage: jjs -fx javaastviewer.js -- <.java files>
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This example demonstrates Java subclassing by Java.extend
+// and javac Compiler and Tree API. This example also uses
+// -fx and javafx TreeView to visualize Java AST as TreeView
+
+if (!$OPTIONS._fx || arguments.length == 0) {
+    print("Usage: jjs -fx javaastviewer.js -- <.java files>");
+    exit(1);
+}
+
+// Java types used
+var Enum = Java.type("java.lang.Enum");
+var HashSet  = Java.type("java.util.HashSet");
+var Name = Java.type("javax.lang.model.element.Name");
+var List = Java.type("java.util.List");
+var Set  = Java.type("java.util.Set");
+var SimpleTreeVisitor = Java.type("com.sun.source.util.SimpleTreeVisitor");
+var StringArray = Java.type("java.lang.String[]");
+var ToolProvider = Java.type("javax.tools.ToolProvider");
+var Tree = Java.type("com.sun.source.tree.Tree");
+
+function javaASTToScriptObject(args) {
+    // properties ignored (javac implementation class properties) in AST view.
+    // may not be exhaustive - any getAbc would become "abc" property or
+    // public field becomes a property of same name.
+    var ignoredProps = new HashSet();
+    for each (var word in 
+        ['extending', 'implementing', 'init', 'mods', 'clazz', 'defs', 
+         'expr', 'tag', 'preferredPosition', 'qualid', 'recvparam',
+         'restype', 'params', 'startPosition', 'thrown',
+         'tree', 'typarams', 'typetag', 'vartype']) {
+        ignoredProps.add(word);
+    }
+
+    // get the system compiler tool
+    var compiler = ToolProvider.systemJavaCompiler;
+
+    // get standard file manager
+    var fileMgr = compiler.getStandardFileManager(null, null, null);
+
+    // make a list of compilation unit from command line argument file names
+    // Using Java.to convert script array (arguments) to a Java String[]
+    var compUnits = fileMgr.getJavaFileObjects(Java.to(args, StringArray));
+
+    // create a new compilation task
+    var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
+
+    // subclass SimpleTreeVisitor - converts Java AST node to
+    // a simple script object by walking through it
+    var ConverterVisitor = Java.extend(SimpleTreeVisitor);
+
+    var visitor = new ConverterVisitor() {
+        // convert java AST node to a friendly script object
+        // which can be viewed. Every node ends up in defaultAction 
+        // method of SimpleTreeVisitor method.
+
+        defaultAction: function (node, p) {
+            var resultObj = {};
+            // Nashorn does not iterate properties and methods of Java objects
+            // But, we can bind properties of any object (including java objects)
+            // to a script object and iterate it!
+            var obj = {};
+            Object.bindProperties(obj, node);
+
+            // we don't want every property, method of java object
+            for (var prop in obj) {
+                var val = obj[prop];
+                var type = typeof val;
+                // ignore 'method' members
+                if (type == 'function' || type == 'undefined') {
+                    continue;
+                }
+
+                // ignore properties from Javac implementation
+                // classes - hack by name!!
+                if (ignoredProps.contains(prop)) {
+                    continue;
+                }
+
+                // subtree - recurse it
+                if (val instanceof Tree) {
+                    resultObj[prop] = visitor.visit(val, p);
+                } else if (val instanceof List) {
+                    // List of trees - recurse each and make an array
+                    var len = val.size();
+                    if (len != 0) {
+                        var arr = [];
+                        for (var j = 0; j < len; j++) {
+                            var e = val[j];
+                            if (e instanceof Tree) {
+                                arr.push(visitor.visit(e, p));
+                            }
+                        }
+                        resultObj[prop] = arr;
+                    }
+                } else if (val instanceof Set) {
+                    // Set - used for modifier flags
+                    // make array
+                    var len = val.size();
+                    if (len != 0) {
+                        var arr = [];
+                        for each (var e in val) {
+                            if (e instanceof Enum || typeof e == 'string') {
+                                arr.push(e.toString());
+                            }
+                        }
+                        resultObj[prop] = arr;
+                    }
+                } else if (val instanceof Enum || val instanceof Name) {
+                    // make string for any Enum or Name
+                    resultObj[prop] = val.toString();
+                } else if (type != 'object') {
+                    // primitives 'as is'
+                    resultObj[prop] = val;
+                }
+            }
+            return resultObj;
+        }
+    }
+
+    // top level object with one property for each compilation unit
+    var scriptObj = {};
+    for each (var cu in task.parse()) {
+        scriptObj[cu.sourceFile.name] = cu.accept(visitor, null);
+    }
+
+    return scriptObj;
+}
+
+// JavaFX classes used
+var StackPane = Java.type("javafx.scene.layout.StackPane");
+var Scene     = Java.type("javafx.scene.Scene");
+var TreeItem  = Java.type("javafx.scene.control.TreeItem");
+var TreeView  = Java.type("javafx.scene.control.TreeView");
+
+// Create a javafx TreeItem to view a script object
+function treeItemForObject(obj, name) {
+    var item = new TreeItem(name);
+    for (var prop in obj) {
+       var node = obj[prop];
+       if (typeof node == 'object') {
+           if (node == null) {
+               // skip nulls
+               continue;
+           }
+           var subitem = treeItemForObject(node, prop);
+       } else {
+           var subitem = new TreeItem(prop + ": " + node);
+       }
+       item.children.add(subitem);
+    }
+
+    item.expanded = true;
+    return item;
+}
+
+var commandArgs = arguments;
+
+// JavaFX start method
+function start(stage) {
+    var obj = javaASTToScriptObject(commandArgs);
+    stage.title = "Java AST Viewer"
+    var rootItem = treeItemForObject(obj, "AST");
+    rootItem.expanded = true;
+    var tree = new TreeView(rootItem);
+    var root = new StackPane();
+    root.children.add(tree);
+    stage.scene = new Scene(root, 300, 450);
+    stage.show();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/javacastcounter.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Usage: jjs javacastcounter.js -- <.java files>
+
+// This example demonstrates Nashorn Java.extend API
+// to subclass a Java class from script.
+
+// This example uses Javac Compiler and Tree API
+// to list type casts used in java source files.
+
+if (arguments.length == 0) {
+    print("Usage: jjs javacastcounter.js -- <.java files>");
+    exit(1);
+}
+
+// Java types used
+var ToolProvider = Java.type("javax.tools.ToolProvider");
+var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
+var Trees = Java.type("com.sun.source.util.Trees");
+var StringArray = Java.type("java.lang.String[]");
+
+// get the system compiler tool
+var compiler = ToolProvider.systemJavaCompiler;
+
+// get standard file manager
+var fileMgr = compiler.getStandardFileManager(null, null, null);
+
+// make a list of compilation unit from command line argument file names
+// Using Java.to convert script array (arguments) to a Java String[]
+var compUnits = fileMgr.getJavaFileObjects(Java.to(arguments, StringArray));
+
+// create a new compilation task
+var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
+
+// SourcePositions object to get positions of AST nodes
+var sourcePositions = Trees.instance(task).sourcePositions;
+
+// Subclass TreeScanner class
+var CastCounter = Java.extend(TreeScanner);
+
+var counter = new CastCounter() {
+    // current CompilationUnitTree
+    compUnit: null,
+    // current LineMap (pos -> line, column)
+    lineMap: null,
+    // current compilation unit's file name
+    fileName: null,
+
+    // overrides of TreeScanner methods
+
+    visitCompilationUnit: function(node, p) {
+        // capture info about current Compilation unit
+        this.compUnit = node;
+        this.lineMap = node.lineMap;
+        this.fileName = node.sourceFile.name;
+
+        // Using Java.super API to call super class method here        
+        return Java.super(counter).visitCompilationUnit(node, p);
+    },
+
+    visitTypeCast: function(node, p) {
+        // print information on this type cast node
+        var pos = sourcePositions.getStartPosition(this.compUnit, node);
+        var line = this.lineMap.getLineNumber(pos);
+        var col = this.lineMap.getColumnNumber(pos);
+        print(node + " @ " + this.fileName + ":" + line + ":" + col);
+
+        // count one more type cast
+        return 1;
+    },
+
+    reduce: function(r1, r2) {
+        return (r1 == null ? 0 : r1) + (r2 == null ? 0 : r2);
+    }
+};
+
+// print total number of type cast nodes seen
+print("Total casts:", counter.scan(task.parse(), null));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/javaimporter.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// JavaImporter along with 'with' statement helps in
+// localized Java class references
+
+function readTextFromURL(url) {
+
+    // equivalent to 
+    // 
+    //    import java.io.*;
+    //    import java.net.*;
+    //    import java.lang.StringBuffer;
+    //
+    // only inside the 'with' statement
+    with (new JavaImporter(java.io, 
+        java.net,
+        java.lang.StringBuilder)) {
+        var buf = new StringBuilder();
+        var u = new URL(url);
+        var reader = new BufferedReader(
+            new InputStreamReader(u.openStream()));
+        var line = null;
+        try {
+            while ((line = reader.readLine()) != null)
+                buf.append(line).append('\n');
+        } finally {
+            reader.close();
+        }
+
+        return buf.toString();
+    }
+}
+
+print(readTextFromURL("https://twitter.com/"));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/javalist.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Java List elements accessed/modified via
+// array element access/update syntax
+
+var ArrayList = Java.type("java.util.ArrayList");
+var list = new ArrayList();
+
+// add elements to list by List's add method calls
+list.add("js");
+list.add("ecmascript");
+list.add("nashorn");
+
+// get by List's get(int) method
+print(list[0]);
+print(list[1]);
+print(list[2]);
+
+// access list elements by indexed access as well
+print(list[0]);
+print(list[1]);
+print(list[2]);
+
+// assign to list elements by index as well
+list[0] = list[0].toUpperCase();
+list[1] = list[1].toUpperCase();
+list[2] = list[2].toUpperCase();
+
+print(list.get(0));
+print(list.get(1));
+print(list.get(2));
+print(list[0]);
+print(list[1]);
+print(list[2]);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/javamap.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Java Map keys as properties
+
+// Demonstrating Java Map key/value can be accessed
+// as property/value from script.
+
+var HashMap = Java.type("java.util.HashMap");
+var map = new HashMap();
+
+// map key-value access by java get/put method calls
+map.put('js', 'nashorn');
+print(map.get('js'));
+
+// access keys of map as properties
+print(map['js']);
+print(map.js);
+
+// also assign new key-value pair 
+// as 'property-value'
+map['language'] = 'java';
+print(map.get("language"));
+print(map.language);
+print(map['language']);
+
+map.answer = 42;
+print(map.get("answer"));
+print(map.answer);
+print(map['answer']);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/javashell.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,146 @@
+#// Usage: jjs -scripting javashell.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple Java "shell" with which you can try out
+// your few liner Java code leaving imports, main etc.
+// And you can leave even compilation as this script
+// takes care boilerplate+compile step for you.
+
+// Java types used
+var Arrays = Java.type("java.util.Arrays");
+var BufferedReader = Java.type("java.io.BufferedReader");
+var FileWriter = Java.type("java.io.FileWriter");
+var LocalDateTime = Java.type("java.time.LocalDateTime");
+var InputStreamReader = Java.type("java.io.InputStreamReader");
+var PrintWriter = Java.type("java.io.PrintWriter");
+var ProcessBuilder = Java.type("java.lang.ProcessBuilder");
+var System = Java.type("java.lang.System");
+
+// read multiple lines of input from stdin till user
+// enters an empty line
+function input(endMarker, prompt) {
+    if (!endMarker) {
+        endMarker = "";
+    }
+
+    if (!prompt) {
+        prompt = " >> ";
+    }
+
+    var str = "";
+    var reader = new BufferedReader(new InputStreamReader(System.in));
+    var line;
+    while (true) {
+        System.out.print(prompt);
+        line = reader.readLine();
+        if (line == null || line == endMarker) {
+            break;
+        }
+        str += line + "\n";
+    }
+    return str;
+}
+
+// write the string to the given file
+function writeTo(file, str) {
+    var w = new PrintWriter(new FileWriter(file));
+    try {
+        w.print(str);
+    } finally {
+        w.close();
+    }
+}
+
+// generate Java code with user's input
+// put inside generated main method
+function generate(className) {
+    var usercode = input();
+    if (usercode == "") {
+        return false;
+    }
+
+    var fullcode = <<EOF
+// userful imports, add more here if you want
+// more imports.
+import static java.lang.System.*;
+import java.io.*;
+import java.net.*;
+import java.math.*;
+import java.nio.file.*;
+import java.time.*;
+import java.time.chrono.*;
+import java.time.format.*;
+import java.time.temporal.*;
+import java.time.zone.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+public class ${className} {
+   public static void main(String[] args) throws Exception {
+       ${usercode}
+   }
+}
+EOF
+
+    writeTo("${className}.java", fullcode);
+    return true;
+}
+
+// execute code command
+function exec(args) {
+    // build child process and start it!
+    new ProcessBuilder(Arrays.asList(args.split(' ')))
+         .inheritIO()
+         .start()
+         .waitFor();
+}
+
+// generate unique name
+function uniqueName() {
+    var now = LocalDateTime.now().toString();
+    // replace unsafe chars with '_' 
+    return "JavaShell" + now.replace(/-|:|\./g, '_');
+}
+
+// read-compile-run loop
+while(true) {
+    var className = uniqueName();
+    if (generate(className)) {
+        exec("javac ${className}.java");
+        exec("java ${className}");
+    } else {
+        break;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/jsadapter_dom.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,189 @@
+#// Usage: jjs -scripting jsadapter_dom.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple example that demonstrates reading XML Rss feed
+// to generate a HTML file from script and show it by browser
+// Uses XML DOM parser and DOM element wrapped by script 
+// "proxy" (JSAdapter constructor)
+
+// Java classes used
+var DocBuilderFac = Java.type("javax.xml.parsers.DocumentBuilderFactory");
+var Node = Java.type("org.w3c.dom.Node");
+var File = Java.type("java.io.File");
+var FileWriter = Java.type("java.io.FileWriter");
+var PrintWriter = Java.type("java.io.PrintWriter");
+
+// constants from Node class
+var ELEMENT_NODE = Node.ELEMENT_NODE;
+var TEXT_NODE = Node.TEXT_NODE;
+
+// parse XML from uri and return Document
+function parseXML(uri) {
+    var docBuilder = DocBuilderFac.newInstance().newDocumentBuilder();
+    return docBuilder["parse(java.lang.String)"](uri);
+}
+
+// get child Elements of given name of the parent element given
+function getChildElements(elem, name) {
+    var nodeList = elem.childNodes;
+    var childElems = [];
+    var len = nodeList.length;
+    for (var i = 0; i < len; i++) {
+        var node = nodeList.item(i);
+        if (node.nodeType == ELEMENT_NODE &&
+            node.tagName == name) {
+            childElems.push(wrapElement(node));
+        }
+    }
+
+    return childElems;
+}
+
+// get concatenated child text content of an Element
+function getElemText(elem) {
+    var nodeList = elem.childNodes;
+    var len = nodeList.length;
+    var text = '';
+    for (var i = 0; i < len; i++) {
+        var node = nodeList.item(i);
+        if (node.nodeType == TEXT_NODE) {
+            text += node.nodeValue;
+        } 
+    }
+
+    return text;
+}
+
+// Wrap DOM Element object as a convenient script object
+// using JSAdapter. JSAdapter is like java.lang.reflect.Proxy
+// in that it allows property access, method calls be trapped
+// by 'magic' methods like __get__, __call__.
+function wrapElement(elem) {
+    if (! elem) {
+        return elem;
+    }
+    return new JSAdapter() {
+        // getter to expose child elements and attributes by name
+        __get__: function(name) {
+            if (typeof name == 'string') {
+                if (name.startsWith('@')) {
+                    var attr = elem.getAttributeNode(name.substring(1));
+                    return !attr? undefined : attr.value;
+                }
+
+                var arr = getChildElements(elem, name);
+                if (arr.length == 1) {
+                    // single child element, expose as single element
+                    return arr[0];
+                } else {
+                    // multiple children of given name, expose as array
+                    return arr;
+                }
+            }
+            return undefined;
+        },
+
+        __call__: function(name) {
+            // toString override to get text content of this Element
+            if (name == 'toString' || name == 'valueOf') {
+                return getElemText(elem);
+            }
+            return undefined;
+        }
+    }
+}
+
+// generate HTML using here-doc and string interpolation
+function getBooksHtml() {
+    var doc = parseXML("http://www.gutenberg.org/cache/epub/feeds/today.rss");
+    // wrap document root Element as script convenient object
+    var rss = wrapElement(doc.documentElement);
+    print("rss file version " + rss['@version']);
+
+    var str = <<HEAD
+
+<html>
+<title>${rss.channel.title}</title>
+<body>
+<h1>${rss.channel.description}</h1>
+<p>
+Published on ${rss.channel.pubDate}
+</p>
+
+HEAD
+
+    var items = rss.channel.item;
+    for each (var i in items) {
+        str += <<LIST
+
+<dl>
+<dt><a href="${i.link}">${i.title}</a></dt>
+<dd>${i.description}</dd>
+</dl>
+
+LIST
+    }
+    str += <<END
+
+</body>
+</html>
+
+END
+    return str;
+}
+
+// write the string to the given file
+function writeTo(file, str) {
+    var w = new PrintWriter(new FileWriter(file));
+    try {
+        w.print(str);
+    } finally {
+        w.close();
+    }
+}
+
+// generate books HTML
+var str = getBooksHtml();
+
+// write to file. __DIR__ is directory where
+// this script is stored.
+var file = new File(__DIR__ + "books.html");
+writeTo(file, str);
+
+// show it by desktop browser
+try {
+    var Desktop = Java.type("java.awt.Desktop");
+    Desktop.desktop.browse(file.toURI());
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/jsobject.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,75 @@
+#// Usage: jjs -scripting -cp . jsobject.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This sample demonstrats how to expose a
+// script friendly object from your java code
+// by implementing jdk.nashorn.api.scripting.JSObject
+
+// compile the java program
+`javac BufferArray.java`;
+
+// print error, if any and exit
+if ($ERR != '') {
+    print($ERR);
+    exit($EXIT);
+}
+
+// create BufferArray
+var BufferArray = Java.type("BufferArray");
+var bb = new BufferArray(10);
+
+// 'magic' methods called to retrieve set/get
+// properties on BufferArray instance
+var len = bb.length;
+print("bb.length = " + len)
+for (var i = 0; i < len; i++) {
+    bb[i] = i*i;
+}
+
+for (var i = 0; i < len; i++) {
+    print(bb[i]);
+}
+
+// get underlying buffer by calling a method
+// on BufferArray magic object
+
+// 'buf' is a function member
+print(typeof bb.buf);
+var buf = bb.buf();
+
+// use retrieved underlying nio buffer
+var cap = buf.capacity();
+print("buf.capacity() = " + cap);
+for (var i = 0; i < cap; i++) {
+   print(buf.get(i));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/jsobject_mapreduce.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,62 @@
+#// Usage: jjs -scripting -cp . jsobject_mapreduce.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Many Array.prototype functions such as map, 
+// filter, reduce, reduceRight, every, some are generic.
+// These functions accept ECMAScript array as well as 
+// many array-like objects including JSObjects.
+// See also http://en.wikipedia.org/wiki/MapReduce
+
+`javac BufferArray.java`;
+
+var BufferArray = Java.type("BufferArray");
+var buf = new BufferArray(10);
+
+var map = Array.prototype.map;
+var filter = Array.prototype.filter;
+var reduce = Array.prototype.reduce;
+
+// make random list of numbers
+for (var i = 0; i < 10; i++)
+    buf[i] = Math.random();
+
+var forEach = Array.prototype.forEach;
+// print numbers in the list
+forEach.call(buf, function(x) print(x));
+
+// print sum of squares of the random numbers
+print("Square sum:",
+    reduce.call(
+        map.call(buf, function(x) x*x), 
+        function(x, y) x + y)
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/jsonviewer.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,120 @@
+#// Usage: jjs -fx jsonviewer.js
+// or
+//        jjs -fx jsonviewer.js -- <url-of-json-doc>
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+if (! $OPTIONS._fx) {
+    print("Usage: jjs -fx jsonviewer.js -- <url-of-json-doc>");
+    exit(1);
+}
+
+// This example downloads a JSON file from a URL and
+// shows the same as a JavaFX tree view.
+
+// Using JavaFX from Nashorn. See also:
+// http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/javafx.html
+
+// JavaFX classes used
+var StackPane = Java.type("javafx.scene.layout.StackPane");
+var Scene     = Java.type("javafx.scene.Scene");
+var TreeItem  = Java.type("javafx.scene.control.TreeItem");
+var TreeView  = Java.type("javafx.scene.control.TreeView");
+
+// read text content of a URL
+function readTextFromURL(url) {
+    // equivalent to 
+    // 
+    //    import java.io.*;
+    //    import java.net.*;
+    //    import java.lang.StringBuffer;
+    //
+    // only inside the 'with' statement
+    with (new JavaImporter(java.io,
+        java.net,
+        java.lang.StringBuilder)) {
+        var buf = new StringBuilder();
+        var u = new URL(url);
+        var reader = new BufferedReader(
+            new InputStreamReader(u.openStream()));
+        var line = null;
+        try {
+            while ((line = reader.readLine()) != null)
+                buf.append(line).append('\n');
+        } finally {
+            reader.close();
+        }
+
+        return buf.toString();
+    }
+}
+
+// Create a javafx TreeItem to view a script object
+function treeItemForObject(obj, name) {
+    var item = new TreeItem(name);
+    for (var prop in obj) {
+       var node = obj[prop];
+       if (typeof node == 'object') {
+           if (node == null) {
+               // skip nulls
+               continue;
+           }
+
+           if (Array.isArray(node) && node.length == 0) {
+               // skip empty arrays
+               continue;
+           }
+
+           var subitem = treeItemForObject(node, prop);
+       } else {
+           var subitem = new TreeItem(prop + ": " + node);
+       }
+       item.children.add(subitem);
+    }
+    return item;
+}
+
+var DEFAULT_URL = "http://api.openweathermap.org/data/2.5/forecast/daily?q=Chennai&amp;mode=json&amp;units=metric&amp;cnt=7`";
+
+var url = arguments.length == 0? DEFAULT_URL : arguments[0];
+var obj = JSON.parse(readTextFromURL(url));
+
+// JavaFX start method
+function start(stage) {
+    stage.title = "JSON Viewer";
+    var rootItem = treeItemForObject(obj, url);
+    var tree = new TreeView(rootItem);
+    var root = new StackPane();
+    root.children.add(tree);
+    stage.scene = new Scene(root, 300, 450);
+    stage.show();
+}
--- a/samples/letter.js	Wed May 28 13:58:46 2014 +0200
+++ b/samples/letter.js	Wed May 28 16:53:43 2014 +0200
@@ -1,3 +1,5 @@
+#// Usage: jjs -scripting letter.js -- <sender> <recipient>
+
 /*
  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/list_mapreduce.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Usage: jjs list_mapreduce.js
+
+// Many Array.prototype functions such as map, 
+// filter, reduce, reduceRight, every, some are generic.
+// These functions accept ECMAScript array as well as 
+// many array-like objects including java.util.ArrayLists.
+// So, you can do map/filter/reduce with Java streams or
+// you can also use Array.prototype functions as below.
+// See also http://en.wikipedia.org/wiki/MapReduce
+
+var ArrayList = Java.type("java.util.ArrayList");
+var list = new ArrayList();
+list.add("nashorn");
+list.add("ecmascript");
+list.add("javascript");
+list.add("js");
+list.add("scheme");
+
+var map = Array.prototype.map;
+var filter = Array.prototype.filter;
+var reduce = Array.prototype.reduce;
+
+// sum of word lengths
+print("Sum word length:",
+    reduce.call(
+        map.call(list, function(x) x.length),
+        function(x, y) x + y)
+);
+
+// filter use to filter out "j*" and concatenate rest with ":"
+// after uppercasing all strings
+print(
+    reduce.call(
+        map.call(
+            filter.call(list, function(x) !x.startsWith("j")),
+            function(x) x.toUpperCase()),
+        function(x, y) x + ":" + y)
+);
+
+// another list example involving numbers
+list.clear();
+// make random list of numbers
+for (var i = 0; i < 10; i++)
+    list.add(Math.random());
+
+var forEach = Array.prototype.forEach;
+// print numbers in the list
+forEach.call(list, function(x) print(x));
+
+// print sum of squares of the random numbers
+print("Square sum:",
+    reduce.call(
+        map.call(list, function(x) x*x), 
+        function(x, y) x + y)
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/locales.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple program that lists available locals. This is ECMAScript
+// port of Java example by @brunoborges
+
+// Java classes used
+var Arrays = Java.type("java.util.Arrays");
+var Collectors = Java.type("java.util.stream.Collectors");
+var JString = Java.type("java.lang.String");
+var Locale = Java.type("java.util.Locale");
+
+var formatStr = "Country : %s \t\t\t\t:\t Country Code : %s";
+
+// Nashorn allows script functions to be passed
+// whereever Java8 lambdas are expected.
+
+// Nashorn also supports "expression closures" supported by
+// Mozilla JavaScript 1.8 version. See also
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/1.8
+
+// The following prints locales in (country) display name order
+var list = Arrays.asList(Locale.getISOCountries())
+    .stream()
+    .map(function(x) new Locale("", x))
+    .sorted(function(c0, c1) c0.displayCountry.compareTo(c1.displayCountry))
+    .map(function(l) JString.format(formatStr, l.displayCountry, l.country))
+    .collect(Collectors.toList());
+
+list.forEach(print);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/logisticmap.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,82 @@
+#// Usage: jjs -fx -scripting logisticmap.js -- <initial_x> <R>
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Logistic map viewer using Java8 Streams and JavaFX
+// See also http://en.wikipedia.org/wiki/Logistic_map
+
+if (!$OPTIONS._fx || arguments.length < 2) {
+    print("Usage: jjs -fx -scripting logisticmap.js -- <initial_x> <R>");
+    exit(1);
+}
+
+// parameters for the logistic map
+var x = parseFloat(arguments[0]);
+var R = parseFloat(arguments[1]);
+var NUM_POINTS = arguments.length > 2? parseFloat(arguments[2]) : 20;
+
+// Java classes used
+var DoubleStream = Java.type('java.util.stream.DoubleStream');
+var LineChart = Java.type("javafx.scene.chart.LineChart");
+var NumberAxis = Java.type("javafx.scene.chart.NumberAxis");
+var Scene = Java.type("javafx.scene.Scene");
+var Stage = Java.type("javafx.stage.Stage");
+var XYChart = Java.type("javafx.scene.chart.XYChart");
+
+function start(stage) {
+    stage.title = "Logistic Map: initial x = ${x}, R = ${R}";
+    // make chart
+    var xAxis = new NumberAxis();
+    var yAxis = new NumberAxis();
+    var lineChart = new LineChart(xAxis, yAxis);
+    xAxis.setLabel("iteration");
+    yAxis.setLabel("x");
+    // make chart data series
+    var series = new XYChart.Series();
+    var data = series.data;
+    // populate data using logistic iteration
+    var i = 0;
+    DoubleStream
+        .generate(function() x = R*x*(1-x))
+        .limit(NUM_POINTS)
+        .forEach(
+            function(value) {
+                data.add(new XYChart.Data(i, value));
+                i++;
+            }
+         );
+    // add to stage
+    var scene = new Scene(lineChart, 800, 600);
+    lineChart.data.add(series);
+    stage.scene = scene;
+    stage.show();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/options.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,37 @@
+#// Usage: jjs -scripting options.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// print all option names and values
+for (i in $OPTIONS) {
+    print(i, '=', $OPTIONS[i]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/readLine.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,38 @@
+#// Usage: jjs -scripting greeting.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// readLine prints prompt and reads user response
+var name = readLine("Your name please: ");
+
+// user name is interpolated within string
+print("Hello ${name}");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/sam_function.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn supports passing script functions whenever
+// a SAM (single abstract method) type object is expected
+
+var System = Java.type("java.lang.System");
+var Timer = Java.type("java.util.Timer");
+var timer = new Timer();
+
+// schedule method accepts java.util.TimerTask
+// which is a single-abstract-method type. you
+// can pass a script function and nashorn will
+// wrap it as SAM implementor.
+
+timer.schedule(function() {
+    print("Hello World!");
+}, 1000);
+
+// wait for timer thread to print by
+// reading from stdin. 
+print("press any key to exit after message from timer...");
+System.in.read();
--- a/samples/shell.js	Wed May 28 13:58:46 2014 +0200
+++ b/samples/shell.js	Wed May 28 16:53:43 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -29,50 +29,53 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/**
- * This is a simple shell tool in JavaScript.
+// Usage: jjs shell.js
+
+/* This is a simple shell tool in JavaScript.
  *
  * Runs any operating system command using Java "exec". When "eval" command is
  * used, evaluates argument(s) as JavaScript code.
  */
 
-var imports = new JavaImporter(java.io, java.lang, java.util);
+(function() {
+    // Java classes used
+    var Arrays = Java.type("java.util.Arrays");
+    var BufferedReader = Java.type("java.io.BufferedReader");
+    var InputStreamReader = Java.type("java.io.InputStreamReader");
+    var ProcessBuilder = Java.type("java.lang.ProcessBuilder");
+    var System = Java.type("java.lang.System");
 
-function prompt() {
-    java.lang.System.out.print(">");
-}
+    // print prompt
+    function prompt() {
+        System.out.print("> ");
+    }
 
-with (imports) {
-    var reader = new BufferedReader(new InputStreamReader(System["in"]));
-    var line = null;
+    var reader = new BufferedReader(new InputStreamReader(System.in));
     prompt();
-    while ((line = reader.readLine()) != null) {
-        if (line != "") {
-            var args = line.split(" ");
+    // read and evaluate each line from stdin
+    reader.lines().forEach(function(line) {
+        if (! line.isEmpty()) {
+            var args = line.split(' ');
             try {
-                if (args[0] == "eval") {
-                    var code = line.substring("eval".length);
+                // special 'eval' command to evaluate JS code
+                if (args[0] == 'eval') {
+                    var code = line.substring('eval'.length);
                     var res = eval(code);
                     if (res != undefined) {
                         print(res);
                     }
                 } else {
-                    var argList = new ArrayList();
-                    for (i in args) { argList.add(args[i]); }                
-                    var procBuilder = new ProcessBuilder(argList);
-                    procBuilder.redirectErrorStream();
-                    var proc = procBuilder.start();
-                    var out = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-                    var line = null;
-                    while ((line = out.readLine()) != null) {
-                        System.out.println(line);
-                    }
-                    proc.waitFor();
+                    // build child process and start it!
+                    new ProcessBuilder(Arrays.asList(args))
+                        .inheritIO()
+                        .start()
+                        .waitFor();
                 }
             } catch (e) {
+                // print exception, if any
                 print(e);
             }
         }
         prompt();
-    }
-}
+    })
+})()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/stack.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// nashorn supports 'stack' property on ECMAScript
+// error objects. This property's value is a string
+// that shows script stack trace.
+
+function g() { 
+    throw new Error("wrong");
+}
+
+function f() {
+    g();
+}
+
+// Output looks something like:
+//
+//  Error: wrong
+//	at g (stack.js:37)
+//	at f (stack.js:41)
+//	at <program> (stack.js:52)
+
+try {
+   f();
+} catch (e) {
+   print(e.stack);
+}
--- a/samples/test.js	Wed May 28 13:58:46 2014 +0200
+++ b/samples/test.js	Wed May 28 16:53:43 2014 +0200
@@ -30,4 +30,3 @@
  */
 
 print("Hello World");
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/uniform_random.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// generate/print 100 uniformly distributed random values
+// and print summary statistics on it
+
+var DoubleStream = Java.type("java.util.stream.DoubleStream");
+
+// pass script function when a lambda is required
+// Math.random passed here for double generator lambda
+// print passed to forEach method
+
+DoubleStream
+    .generate(Math.random)
+    .limit(100)
+    .forEach(print);
+
+print(DoubleStream
+    .generate(Math.random)
+    .limit(100)
+    .summaryStatistics());
--- a/samples/uniq.js	Wed May 28 13:58:46 2014 +0200
+++ b/samples/uniq.js	Wed May 28 16:53:43 2014 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -29,27 +29,28 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/**
- * Prints unique lines from a given file.
- */
+// Usage: jjs uniq.js
+// or: jjs uniq.js -- <file>
 
-if (arguments.length != 1) {
-    print("Usage: jjs uniq.js -- <file>");
-    java.lang.System.exit(1);
+// omit repeated lines and print unique lines
+
+var BufferedReader = Java.type("java.io.BufferedReader");
+var FileReader = Java.type("java.io.FileReader");
+var InputStreamReader = Java.type("java.io.InputStreamReader");
+var System = Java.type("java.lang.System");
+
+// use object as set - but insertion order preserved
+var uniqueLines = {};
+var reader = arguments.length > 0 ?
+    new FileReader(arguments[0])  :
+    new InputStreamReader(System.in);
+reader = new BufferedReader(reader);
+
+// add unique lines
+reader.lines().forEach(function(line) {
+    uniqueLines[line] = true;
+})
+
+for (line in uniqueLines) {
+    print(line);
 }
-
-var imports = new JavaImporter(java.io);
-
-var uniqueLines = {};
-with (imports) {
-    var reader = new BufferedReader(new FileReader(arguments[0]));
-    while ((line = reader.readLine()) != null) {
-        // using a JS object as a map...
-        uniqueLines[line] = true;
-    }
-}
-
-// now print the collected lines
-for (i in uniqueLines) {
-    print(i);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/uniqs.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Usage: jjs uniqs.js -- <file>
+// omit repeated lines and print unique lines
+// But this version uses Stream API 
+
+if (arguments.length < 1) {
+    print("Usage: jjs uniqs.js -- <file>");
+    exit(1);
+}
+
+var Files = Java.type("java.nio.file.Files");
+var FileSystems = Java.type("java.nio.file.FileSystems");
+print('Unique lines:',
+   Files
+    .lines(FileSystems.default.getPath(arguments[0]))
+    .distinct()
+    .peek(print)
+    .count());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/weather.js	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,63 @@
+#// usage: jjs -scripting weather.js
+
+/*
+ * Copyright (c) 2014, 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
+ * are met:
+ * 
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   - Neither the name of Oracle nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Simple nashorn example showing back-quote exec process,
+// JSON and Java8 streams
+
+var Arrays = Java.type("java.util.Arrays");
+
+// use curl to download JSON weather data from the net
+// use backquote -scripting mode syntax to exec a process
+
+`curl http://api.openweathermap.org/data/2.5/forecast/daily?q=Chennai&amp;mode=json&amp;units=metric&amp;cnt=7`;
+
+// parse JSON
+var weather = JSON.parse($OUT);
+
+// pull out humidity as array
+var humidity = weather.list.map(function(curVal) {
+    return curVal.humidity;
+})
+
+// Stream API to print stat
+print("Humidity");
+print(Arrays["stream(int[])"](humidity).summaryStatistics());
+
+// pull maximum day time temperature
+var temp = weather.list.map(function(curVal) {
+    return curVal.temp.max;
+});
+
+// Stream API to print stat
+print("Max Temperature");
+print(Arrays["stream(double[])"](temp).summaryStatistics());
--- a/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/internal/dynalink/beans/AccessibleMembersLookup.java	Wed May 28 16:53:43 2014 +0200
@@ -211,7 +211,8 @@
         if(!CheckRestrictedPackage.isRestrictedClass(clazz)) {
             searchSuperTypes = false;
             for(Method method: clazz.getMethods()) {
-                if(instance != Modifier.isStatic(method.getModifiers())) {
+                final boolean isStatic = Modifier.isStatic(method.getModifiers());
+                if(instance != isStatic) {
                     final MethodSignature sig = new MethodSignature(method);
                     if(!methods.containsKey(sig)) {
                         final Class<?> declaringClass = method.getDeclaringClass();
@@ -228,7 +229,10 @@
                             //generate the said synthetic delegators.
                             searchSuperTypes = true;
                         } else {
-                            methods.put(sig, method);
+                            // don't allow inherited static
+                            if (!isStatic || clazz == declaringClass) {
+                                methods.put(sig, method);
+                            }
                         }
                     }
                 }
@@ -245,7 +249,8 @@
             searchSuperTypes = true;
         }
 
-        if(searchSuperTypes) {
+        // don't need to search super types for static methods
+        if(instance && searchSuperTypes) {
             // If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is
             // public, but some of its methods claim that their declaring class is non-public. We'll try superclasses
             // and implemented interfaces then looking for public ones.
--- a/src/jdk/internal/dynalink/beans/BeanLinker.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/internal/dynalink/beans/BeanLinker.java	Wed May 28 16:53:43 2014 +0200
@@ -113,6 +113,8 @@
             // explicit property is beneficial for them.
             // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
             setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
+        } else if(List.class.isAssignableFrom(clazz)) {
+            setPropertyGetter("length", GET_COLLECTION_LENGTH, ValidationType.INSTANCE_OF);
         }
     }
 
--- a/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Wed May 28 16:53:43 2014 +0200
@@ -136,7 +136,13 @@
         final Field[] fields = clazz.getFields();
         final Collection<Field> cfields = new ArrayList<>(fields.length);
         for(Field field: fields) {
-            if(instance != Modifier.isStatic(field.getModifiers()) && isAccessible(field)) {
+            final boolean isStatic = Modifier.isStatic(field.getModifiers());
+            if(isStatic && clazz != field.getDeclaringClass()) {
+                // ignore inherited static fields
+                continue;
+            }
+
+            if(instance != isStatic && isAccessible(field)) {
                 cfields.add(field);
             }
         }
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed May 28 16:53:43 2014 +0200
@@ -27,16 +27,14 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.io.Reader;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.net.URL;
-import java.nio.charset.Charset;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.Permissions;
@@ -125,20 +123,20 @@
         }
     }
 
-    // load engine.js and return content as a char[]
-    private static char[] loadEngineJSSource() {
+    // load engine.js
+    private static Source loadEngineJSSource() {
         final String script = "resources/engine.js";
         try {
-            final InputStream is = AccessController.doPrivileged(
-                    new PrivilegedExceptionAction<InputStream>() {
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Source>() {
                         @Override
-                        public InputStream run() throws Exception {
+                        public Source run() throws IOException {
                             final URL url = NashornScriptEngine.class.getResource(script);
-                            return url.openStream();
+                            return sourceFor(NashornException.ENGINE_SCRIPT_SOURCE_NAME, url);
                         }
-                    });
-            return Source.readFully(new InputStreamReader(is));
-        } catch (final PrivilegedActionException | IOException e) {
+                    }
+            );
+        } catch (final PrivilegedActionException e) {
             if (Context.DEBUG) {
                 e.printStackTrace();
             }
@@ -147,7 +145,7 @@
     }
 
     // Source object for engine.js
-    private static final Source ENGINE_SCRIPT_SRC = new Source(NashornException.ENGINE_SCRIPT_SOURCE_NAME, loadEngineJSSource());
+    private static final Source ENGINE_SCRIPT_SRC = loadEngineJSSource();
 
     NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
         this(factory, DEFAULT_OPTIONS, appLoader);
@@ -282,19 +280,14 @@
 
     private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException {
         try {
-            if (reader instanceof URLReader) {
-                final URL url = ((URLReader)reader).getURL();
-                final Charset cs = ((URLReader)reader).getCharset();
-                return new Source(url.toString(), url, cs);
-            }
-            return new Source(getScriptName(ctxt), Source.readFully(reader));
-        } catch (final IOException e) {
+            return sourceFor(getScriptName(ctxt), reader);
+        } catch (IOException e) {
             throw new ScriptException(e);
         }
     }
 
     private static Source makeSource(final String src, final ScriptContext ctxt) {
-        return new Source(getScriptName(ctxt), src);
+        return sourceFor(getScriptName(ctxt), src);
     }
 
     private static String getScriptName(final ScriptContext ctxt) {
@@ -532,6 +525,31 @@
         return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
     }
 
+    private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
+        final Global oldGlobal = Context.getGlobal();
+        final boolean globalChanged = (oldGlobal != ctxtGlobal);
+        try {
+            if (globalChanged) {
+                Context.setGlobal(ctxtGlobal);
+            }
+
+            final ScriptFunction script = mgcs.getFunction(ctxtGlobal);
+
+            // set ScriptContext variables if ctxt is non-null
+            if (ctxt != null) {
+                setContextVariables(ctxtGlobal, ctxt);
+            }
+            return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+        } catch (final Exception e) {
+            throwAsScriptException(e, ctxtGlobal);
+            throw new AssertionError("should not reach here");
+        } finally {
+            if (globalChanged) {
+                Context.setGlobal(oldGlobal);
+            }
+        }
+    }
+
     private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
         if (script == null) {
             return null;
@@ -578,18 +596,38 @@
     }
 
     private CompiledScript asCompiledScript(final Source source) throws ScriptException {
-        final ScriptFunction func = compileImpl(source, context);
+        final Context.MultiGlobalCompiledScript mgcs;
+        final ScriptFunction func;
+        final Global oldGlobal = Context.getGlobal();
+        final Global newGlobal = getNashornGlobalFrom(context);
+        final boolean globalChanged = (oldGlobal != newGlobal);
+        try {
+            if (globalChanged) {
+                Context.setGlobal(newGlobal);
+            }
+
+            mgcs = nashornContext.compileScript(source);
+            func = mgcs.getFunction(newGlobal);
+        } catch (final Exception e) {
+            throwAsScriptException(e, newGlobal);
+            throw new AssertionError("should not reach here");
+        } finally {
+            if (globalChanged) {
+                Context.setGlobal(oldGlobal);
+            }
+        }
+
         return new CompiledScript() {
             @Override
             public Object eval(final ScriptContext ctxt) throws ScriptException {
                 final Global globalObject = getNashornGlobalFrom(ctxt);
-                // Are we running the script in the correct global?
+                // Are we running the script in the same global in which it was compiled?
                 if (func.getScope() == globalObject) {
                     return evalImpl(func, ctxt, globalObject);
                 }
-                // ScriptContext with a different global. Compile again!
-                // Note that we may still hit per-global compilation cache.
-                return evalImpl(compileImpl(source, ctxt), ctxt, globalObject);
+
+                // different global
+                return evalImpl(mgcs, ctxt, globalObject);
             }
             @Override
             public ScriptEngine getEngine() {
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed May 28 16:53:43 2014 +0200
@@ -1826,7 +1826,7 @@
      * doing an on-demand ("just-in-time") compilation, then we aren't generating code for inner functions.
      */
     private boolean compileOutermostOnly() {
-        return RecompilableScriptFunctionData.LAZY_COMPILATION || compiler.isOnDemandCompilation();
+        return compiler.isOnDemandCompilation() || compiler.getScriptEnvironment()._lazy_compilation;
     }
 
     @Override
@@ -2296,7 +2296,10 @@
 
             if (value == null) {
                 gettersSetters.add(propertyNode);
-            } else if (key.equals(ScriptObject.PROTO_PROPERTY_NAME)) {
+            } else if (propertyNode.getKey() instanceof IdentNode &&
+                       key.equals(ScriptObject.PROTO_PROPERTY_NAME)) {
+                // ES6 draft compliant __proto__ inside object literal
+                // Identifier key and name is __proto__
                 protoNode = value;
                 continue;
             }
--- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Wed May 28 16:53:43 2014 +0200
@@ -25,8 +25,6 @@
 
 package jdk.nashorn.internal.codegen;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
-import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
 import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BUILTINS_TRANSFORMED;
 import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BYTECODE_GENERATED;
 import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.BYTECODE_INSTALLED;
@@ -42,10 +40,6 @@
 import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
 
 import java.io.PrintWriter;
-import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -53,22 +47,21 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
-import java.util.Map.Entry;
-import java.util.function.Consumer;
-
 import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
 import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
 import jdk.nashorn.internal.ir.LexicalContext;
-import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
+import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit;
-import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.Node;
 import jdk.nashorn.internal.ir.SplitNode;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.runtime.CodeInstaller;
 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.logging.DebugLogger;
@@ -496,13 +489,17 @@
             Class<?> rootClass = null;
             long length = 0L;
 
-            for (final Entry<String, byte[]> entry : compiler.getBytecode().entrySet()) {
+            final CodeInstaller<?> codeInstaller = compiler.getCodeInstaller();
+
+            final Map<String, byte[]> bytecode = compiler.getBytecode();
+
+            for (final Entry<String, byte[]> entry : bytecode.entrySet()) {
                 final String className = entry.getKey();
                 //assert !first || className.equals(compiler.getFirstCompileUnit().getUnitClassName()) : "first=" + first + " className=" + className + " != " + compiler.getFirstCompileUnit().getUnitClassName();
                 final byte[] code = entry.getValue();
                 length += code.length;
 
-                final Class<?> clazz = compiler.getCodeInstaller().install(Compiler.binaryName(className), code);
+                final Class<?> clazz = codeInstaller.install(className, code);
                 if (first) {
                     rootClass = clazz;
                     first = false;
@@ -514,46 +511,12 @@
                 throw new CompilationException("Internal compiler error: root class not found!");
             }
 
-            // do these in parallel, this significantly reduces class installation overhead
-            // however - it still means that every thread needs a separate doPrivileged
             final Object[] constants = compiler.getConstantData().toArray();
-            installedClasses.entrySet().parallelStream().forEach(
-                new Consumer<Entry<String, Class<?>>>() {
-                    @Override
-                    public void accept(final Entry<String, Class<?>> entry) {
-                        try {
-                            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
-                                @Override
-                                public Void run() {
-                                    try {
-                                        final Class<?> clazz = entry.getValue();
-                                        log.fine("Initializing source for ", clazz);
-                                        //use reflection to write source and constants table to installed classes
-                                        final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
-                                        sourceField.setAccessible(true);
-                                        sourceField.set(null, compiler.getSource());
-
-                                        log.fine("Initializing constants for ", clazz);
-                                        final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
-                                        constantsField.setAccessible(true);
-                                        constantsField.set(null, constants);
-                                    } catch (final IllegalAccessException | NoSuchFieldException e) {
-                                        throw new RuntimeException(e);
-                                    }
-                                    return null;
-                                }
-                            });
-                        } catch (final PrivilegedActionException e) {
-                            throw new RuntimeException(e);
-                        }
-                    }
-                });
-            log.fine("Done");
-            log.fine("Done");
+            codeInstaller.initialize(installedClasses.values(), compiler.getSource(), constants);
 
             // index recompilable script function datas in the constant pool
             final Map<RecompilableScriptFunctionData, RecompilableScriptFunctionData> rfns = new IdentityHashMap<>();
-            for (final Object constant: compiler.getConstantData().getConstants()) {
+            for (final Object constant: constants) {
                 if (constant instanceof RecompilableScriptFunctionData) {
                     final RecompilableScriptFunctionData rfn = (RecompilableScriptFunctionData)constant;
                     rfns.put(rfn, rfn);
@@ -566,6 +529,10 @@
                 unit.initializeFunctionsCode();
             }
 
+            if (!compiler.isOnDemandCompilation()) {
+                codeInstaller.storeCompiledScript(compiler.getSource(), compiler.getFirstCompileUnit().getUnitClassName(), bytecode, constants);
+            }
+
             // remove installed bytecode from table in case compiler is reused
             for (final String className : installedClasses.keySet()) {
                 log.fine("Removing installed class ", quote(className), " from bytecode table...");
--- a/src/jdk/nashorn/internal/codegen/CompileUnit.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/codegen/CompileUnit.java	Wed May 28 16:53:43 2014 +0200
@@ -29,7 +29,6 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.TreeSet;
-
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
 
@@ -38,7 +37,7 @@
  */
 public final class CompileUnit implements Comparable<CompileUnit> {
     /** Current class name */
-    private String className;
+    private final String className;
 
     /** Current class generator */
     private ClassEmitter classEmitter;
@@ -173,14 +172,6 @@
         return className;
     }
 
-    /**
-     * Reset the class name for this compile unit
-     * @param className new class name
-     */
-    public void setUnitClassName(final String className) {
-        this.className = className;
-    }
-
     private static String shortName(final String name) {
         return name.lastIndexOf('/') == -1 ? name : name.substring(name.lastIndexOf('/') + 1);
     }
--- a/src/jdk/nashorn/internal/codegen/ConstantData.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/codegen/ConstantData.java	Wed May 28 16:53:43 2014 +0200
@@ -27,12 +27,9 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
 
@@ -209,10 +206,6 @@
         return index;
     }
 
-    Collection<Object> getConstants() {
-        return Collections.unmodifiableList(constants);
-    }
-
     Object[] toArray() {
         return constants.toArray();
     }
--- a/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Wed May 28 16:53:43 2014 +0200
@@ -210,9 +210,8 @@
         // Generate the object class and property map in case this function is ever used as constructor
         final int         fieldCount         = getPaddedFieldCount(newFunctionNode.getThisProperties());
         final String      allocatorClassName = Compiler.binaryName(getClassName(fieldCount));
-        final PropertyMap allocatorMap       = PropertyMap.newMap(null, 0, fieldCount, 0);
+        final PropertyMap allocatorMap       = PropertyMap.newMap(null, allocatorClassName, 0, fieldCount, 0);
         final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData(
-                compiler.getContext(),
                 newFunctionNode,
                 compiler.getCodeInstaller(),
                 allocatorClassName,
--- a/src/jdk/nashorn/internal/codegen/MapCreator.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/codegen/MapCreator.java	Wed May 28 16:53:43 2014 +0200
@@ -90,7 +90,7 @@
             }
         }
 
-        return PropertyMap.newMap(properties, fieldCount, fieldMaximum, 0);
+        return PropertyMap.newMap(properties, structure.getName(), fieldCount, fieldMaximum, 0);
     }
 
     PropertyMap makeSpillMap(final boolean hasArguments) {
@@ -113,7 +113,7 @@
             }
         }
 
-        return PropertyMap.newMap(properties, 0, 0, spillIndex);
+        return PropertyMap.newMap(properties, structure.getName(), 0, 0, spillIndex);
     }
 
     /**
--- a/src/jdk/nashorn/internal/ir/BinaryNode.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/ir/BinaryNode.java	Wed May 28 16:53:43 2014 +0200
@@ -242,6 +242,12 @@
         case INSTANCEOF: {
             return Type.BOOLEAN;
         }
+        case COMMALEFT: {
+            return lhs.getType(localVariableTypes);
+        }
+        case COMMARIGHT: {
+            return rhs.getType(localVariableTypes);
+        }
         default:
             if (isComparison()) {
                 return Type.BOOLEAN;
--- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Wed May 28 16:53:43 2014 +0200
@@ -25,6 +25,8 @@
 
 package jdk.nashorn.internal.ir.debug;
 
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -88,7 +90,7 @@
      * @return JSON string representation of AST of the supplied code
      */
     public static String parse(final Context context, final String code, final String name, final boolean includeLoc) {
-        final Parser       parser     = new Parser(context.getEnv(), new Source(name, code), new Context.ThrowErrorManager(), context.getEnv()._strict, context.getLogger(Parser.class));
+        final Parser       parser     = new Parser(context.getEnv(), sourceFor(name, code), new Context.ThrowErrorManager(), context.getEnv()._strict, context.getLogger(Parser.class));
         final JSONWriter   jsonWriter = new JSONWriter(includeLoc);
         try {
             final FunctionNode functionNode = parser.parse(); //symbol name is ":program", default
--- a/src/jdk/nashorn/internal/lookup/Lookup.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/lookup/Lookup.java	Wed May 28 16:53:43 2014 +0200
@@ -146,6 +146,9 @@
         if (from == int.class) {
             //fallthru
         } else if (from == long.class) {
+            if (to == int.class) {
+                return MH.filterArguments(mh, n, JSType.TO_INT32_L.methodHandle());
+            }
             //fallthru
         } else if (from == double.class) {
             if (to == int.class) {
@@ -169,7 +172,7 @@
         }
 
         //use a standard cast - we don't need to check JavaScript special cases
-        return MH.explicitCastArguments(mh, mh.type().changeParameterType(2, to));
+        return MH.explicitCastArguments(mh, mh.type().changeParameterType(n, from));
     }
 
     /**
@@ -189,6 +192,9 @@
         if (retType == int.class) {
             //fallthru
         } else if (retType == long.class) {
+            if (type == int.class) {
+                return MH.filterReturnValue(mh, JSType.TO_INT32_L.methodHandle());
+            }
             //fallthru
         } else if (retType == double.class) {
             if (type == int.class) {
--- a/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Wed May 28 16:53:43 2014 +0200
@@ -95,7 +95,7 @@
     }
 
     @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
-    public static Object byteOffset(final Object self) {
+    public static int byteOffset(final Object self) {
         return ((ArrayBufferView)self).byteOffset;
     }
 
@@ -244,7 +244,7 @@
         return (int)(length & Integer.MAX_VALUE);
     }
 
-    protected static Object subarrayImpl(final Object self, final Object begin0, final Object end0) {
+    protected static ScriptObject subarrayImpl(final Object self, final Object begin0, final Object end0) {
         final ArrayBufferView arrayView       = (ArrayBufferView)self;
         final int             byteOffset      = arrayView.byteOffset;
         final int             bytesPerElement = arrayView.bytesPerElement();
--- a/src/jdk/nashorn/internal/objects/Global.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/Global.java	Wed May 28 16:53:43 2014 +0200
@@ -1973,6 +1973,13 @@
         // Object.getPrototypeOf(Function.prototype) === Object.prototype
         anon.setInitialProto(ObjectPrototype);
 
+        // ES6 draft compliant __proto__ property of Object.prototype
+        // accessors on Object.prototype for "__proto__"
+        final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", ScriptObject.GETPROTO);
+        final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", ScriptObject.SETPROTOCHECK);
+        ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
+
+
         // Function valued properties of Function.prototype were not properly
         // initialized. Because, these were created before global.function and
         // global.object were not initialized.
--- a/src/jdk/nashorn/internal/objects/NativeArray.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeArray.java	Wed May 28 16:53:43 2014 +0200
@@ -29,6 +29,7 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
 
@@ -387,6 +388,27 @@
     }
 
     /**
+     * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in
+     * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set
+     * method in such cases. This is because set method uses inherited setters (if any)
+     * from any object in proto chain such as Array.prototype, Object.prototype.
+     * This method directly sets a particular element value in the current object.
+     *
+     * @param index key for property
+     * @param value value to define
+     */
+    @Override
+    public final void defineOwnProperty(final int index, final Object value) {
+        assert isValidArrayIndex(index) : "invalid array index";
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        if (longIndex >= getArray().length()) {
+            // make array big enough to hold..
+            setArray(getArray().ensure(longIndex));
+        }
+        setArray(getArray().set(index, value, false));
+    }
+
+    /**
      * Return the array contents upcasted as an ObjectArray, regardless of
      * representation
      *
@@ -404,8 +426,8 @@
      * @return true if argument is an array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object isArray(final Object self, final Object arg) {
-        return isArray(arg) || arg instanceof JSObject && ((JSObject)arg).isArray();
+    public static boolean isArray(final Object self, final Object arg) {
+        return isArray(arg) || (arg instanceof JSObject && ((JSObject)arg).isArray());
     }
 
     /**
@@ -516,7 +538,7 @@
      * @return locale specific string representation for array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleString(final Object self) {
+    public static String toLocaleString(final Object self) {
         final StringBuilder sb = new StringBuilder();
         final Iterator<Object> iter = arrayLikeIterator(self, true);
 
@@ -562,7 +584,7 @@
      * @return the new NativeArray
      */
     @Constructor(arity = 1)
-    public static Object construct(final boolean newObj, final Object self, final Object... args) {
+    public static NativeArray construct(final boolean newObj, final Object self, final Object... args) {
         switch (args.length) {
         case 0:
             return new NativeArray(0);
@@ -615,7 +637,7 @@
      * @return the new NativeArray
      */
     @SpecializedConstructor
-    public static Object construct(final boolean newObj, final Object self) {
+    public static NativeArray construct(final boolean newObj, final Object self) {
         return new NativeArray(0);
     }
 
@@ -645,7 +667,7 @@
      * @return the new NativeArray
      */
     @SpecializedConstructor
-    public static Object construct(final boolean newObj, final Object self, final int length) {
+    public static NativeArray construct(final boolean newObj, final Object self, final int length) {
         if (length >= 0) {
             return new NativeArray(length);
         }
@@ -664,7 +686,7 @@
      * @return the new NativeArray
      */
     @SpecializedConstructor
-    public static Object construct(final boolean newObj, final Object self, final long length) {
+    public static NativeArray construct(final boolean newObj, final Object self, final long length) {
         if (length >= 0L && length <= JSType.MAX_UINT) {
             return new NativeArray(length);
         }
@@ -683,7 +705,7 @@
      * @return the new NativeArray
      */
     @SpecializedConstructor
-    public static Object construct(final boolean newObj, final Object self, final double length) {
+    public static NativeArray construct(final boolean newObj, final Object self, final double length) {
         final long uint32length = JSType.toUint32(length);
 
         if (uint32length == length) {
@@ -701,7 +723,7 @@
      * @return resulting NativeArray
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object concat(final Object self, final Object... args) {
+    public static NativeArray concat(final Object self, final Object... args) {
         final ArrayList<Object> list = new ArrayList<>();
         concatToList(list, Global.toObject(self));
 
@@ -748,7 +770,7 @@
      * @return string representation after join
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object join(final Object self, final Object separator) {
+    public static String join(final Object self, final Object separator) {
         final StringBuilder    sb   = new StringBuilder();
         final Iterator<Object> iter = arrayLikeIterator(self, true);
         final String           sep  = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator);
@@ -1095,7 +1117,7 @@
      * @return sorted array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object sort(final Object self, final Object comparefn) {
+    public static ScriptObject sort(final Object self, final Object comparefn) {
         try {
             final ScriptObject sobj    = (ScriptObject) self;
             final long         len     = JSType.toUint32(sobj.getLength());
@@ -1299,7 +1321,7 @@
      * @return index of element, or -1 if not found
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object indexOf(final Object self, final Object searchElement, final Object fromIndex) {
+    public static long indexOf(final Object self, final Object searchElement, final Object fromIndex) {
         try {
             final ScriptObject sobj = (ScriptObject)Global.toObject(self);
             final long         len  = JSType.toUint32(sobj.getLength());
@@ -1335,7 +1357,7 @@
      * @return index of element, or -1 if not found
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object lastIndexOf(final Object self, final Object... args) {
+    public static long lastIndexOf(final Object self, final Object... args) {
         try {
             final ScriptObject sobj = (ScriptObject)Global.toObject(self);
             final long         len  = JSType.toUint32(sobj.getLength());
@@ -1370,7 +1392,7 @@
      * @return true if callback function return true for every element in the array, false otherwise
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object every(final Object self, final Object callbackfn, final Object thisArg) {
+    public static boolean every(final Object self, final Object callbackfn, final Object thisArg) {
         return applyEvery(Global.toObject(self), callbackfn, thisArg);
     }
 
@@ -1394,7 +1416,7 @@
      * @return true if callback function returned true for any element in the array, false otherwise
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object some(final Object self, final Object callbackfn, final Object thisArg) {
+    public static boolean some(final Object self, final Object callbackfn, final Object thisArg) {
         return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) {
             private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
 
@@ -1435,7 +1457,7 @@
      * @return array with elements transformed by map function
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object map(final Object self, final Object callbackfn, final Object thisArg) {
+    public static NativeArray map(final Object self, final Object callbackfn, final Object thisArg) {
         return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) {
             private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
 
@@ -1464,7 +1486,7 @@
      * @return filtered array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object filter(final Object self, final Object callbackfn, final Object thisArg) {
+    public static NativeArray filter(final Object self, final Object callbackfn, final Object thisArg) {
         return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) {
             private long to = 0;
             private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
--- a/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Wed May 28 16:53:43 2014 +0200
@@ -95,7 +95,7 @@
      * @return new NativeArrayBuffer
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+    public static NativeArrayBuffer constructor(final boolean newObj, final Object self, final Object... args) {
         if (!newObj) {
             throw typeError("constructor.requires.new", "ArrayBuffer");
         }
@@ -145,7 +145,7 @@
      * @return new array buffer, sliced
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object slice(final Object self, final Object begin0, final Object end0) {
+    public static NativeArrayBuffer slice(final Object self, final Object begin0, final Object end0) {
         final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self;
         final int               byteLength  = arrayBuffer.getByteLength();
         final int               begin       = adjustIndex(JSType.toInt32(begin0), byteLength);
@@ -213,11 +213,9 @@
 
     ByteBuffer getBuffer(final int offset) {
         return (ByteBuffer)nb.duplicate().position(offset);
-//        return ByteBuffer.wrap(buffer, offset, buffer.length - offset);
     }
 
     ByteBuffer getBuffer(final int offset, final int length) {
         return (ByteBuffer)getBuffer(offset).limit(length);
-        //return ByteBuffer.wrap(buffer, offset, length);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeBoolean.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeBoolean.java	Wed May 28 16:53:43 2014 +0200
@@ -110,7 +110,7 @@
      * @return string representation of this boolean
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self) {
+    public static String toString(final Object self) {
         return getBoolean(self).toString();
     }
 
@@ -121,7 +121,7 @@
      * @return value of this boolean
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object valueOf(final Object self) {
+    public static boolean valueOf(final Object self) {
         return getBoolean(self);
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeDataView.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeDataView.java	Wed May 28 16:53:43 2014 +0200
@@ -131,7 +131,7 @@
      * @return newly constructed DataView object
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+    public static NativeDataView constructor(final boolean newObj, final Object self, final Object... args) {
         if (args.length == 0 || !(args[0] instanceof NativeArrayBuffer)) {
             throw typeError("not.an.arraybuffer.in.dataview");
         }
@@ -157,7 +157,7 @@
      * @return newly constructed DataView object
      */
     @SpecializedConstructor
-    public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
+    public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
         if (!(arrBuf instanceof NativeArrayBuffer)) {
             throw typeError("not.an.arraybuffer.in.dataview");
         }
@@ -175,7 +175,7 @@
      * @return newly constructed DataView object
      */
     @SpecializedConstructor
-    public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
+    public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
         if (!(arrBuf instanceof NativeArrayBuffer)) {
             throw typeError("not.an.arraybuffer.in.dataview");
         }
@@ -434,7 +434,7 @@
     @SpecializedFunction
     public static long getUint32(final Object self, final int byteOffset) {
         try {
-            return 0xFFFFFFFFL & getBuffer(self, false).getInt(JSType.toInt32(byteOffset));
+            return JSType.MAX_UINT & getBuffer(self, false).getInt(JSType.toInt32(byteOffset));
         } catch (final IllegalArgumentException iae) {
             throw rangeError(iae, "dataview.offset");
         }
@@ -451,7 +451,7 @@
     @SpecializedFunction
     public static long getUint32(final Object self, final int byteOffset, final boolean littleEndian) {
         try {
-            return 0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
+            return JSType.MAX_UINT & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
         } catch (final IllegalArgumentException iae) {
             throw rangeError(iae, "dataview.offset");
         }
--- a/src/jdk/nashorn/internal/objects/NativeDate.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeDate.java	Wed May 28 16:53:43 2014 +0200
@@ -226,7 +226,7 @@
      * @return Date interpreted from the string, or NaN for illegal values
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object parse(final Object self, final Object string) {
+    public static double parse(final Object self, final Object string) {
         return parseDateString(JSType.toString(string));
     }
 
@@ -238,7 +238,7 @@
      * @return a time clip according to the ECMA specification
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 7, where = Where.CONSTRUCTOR)
-    public static Object UTC(final Object self, final Object... args) {
+    public static double UTC(final Object self, final Object... args) {
         final NativeDate nd = new NativeDate(0);
         final double[] d = convertCtorArgs(args);
         final double time = d == null ? Double.NaN : timeClip(makeDate(d));
@@ -253,8 +253,8 @@
      * @return a Date that points to the current moment in time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object now(final Object self) {
-        return (double)System.currentTimeMillis();
+    public static long now(final Object self) {
+        return System.currentTimeMillis();
     }
 
     /**
@@ -264,7 +264,7 @@
      * @return string value that represents the Date in the current time zone
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self) {
+    public static String toString(final Object self) {
         return toStringImpl(self, FORMAT_DATE_TIME);
     }
 
@@ -275,7 +275,7 @@
      * @return string value with the "date" part of the Date in the current time zone
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toDateString(final Object self) {
+    public static String toDateString(final Object self) {
         return toStringImpl(self, FORMAT_DATE);
     }
 
@@ -286,7 +286,7 @@
      * @return string value with "time" part of Date in the current time zone
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toTimeString(final Object self) {
+    public static String toTimeString(final Object self) {
         return toStringImpl(self, FORMAT_TIME);
     }
 
@@ -297,7 +297,7 @@
      * @return string value that represents the Data in the current time zone and locale
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleString(final Object self) {
+    public static String toLocaleString(final Object self) {
         return toStringImpl(self, FORMAT_LOCAL_DATE_TIME);
     }
 
@@ -308,7 +308,7 @@
      * @return string value with the "date" part of the Date in the current time zone and locale
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleDateString(final Object self) {
+    public static String toLocaleDateString(final Object self) {
         return toStringImpl(self, FORMAT_LOCAL_DATE);
     }
 
@@ -319,7 +319,7 @@
      * @return string value with the "time" part of Date in the current time zone and locale
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleTimeString(final Object self) {
+    public static String toLocaleTimeString(final Object self) {
         return toStringImpl(self, FORMAT_LOCAL_TIME);
     }
 
@@ -330,7 +330,7 @@
      * @return valueOf - a number which is this time value
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object valueOf(final Object self) {
+    public static double valueOf(final Object self) {
         final NativeDate nd = getNativeDate(self);
         return (nd != null) ? nd.getTime() : Double.NaN;
     }
@@ -342,7 +342,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getTime(final Object self) {
+    public static double getTime(final Object self) {
         final NativeDate nd = getNativeDate(self);
         return (nd != null) ? nd.getTime() : Double.NaN;
     }
@@ -365,7 +365,7 @@
      * @return UTC full year
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCFullYear(final Object self) {
+    public static double getUTCFullYear(final Object self) {
         return getUTCField(self, YEAR);
     }
 
@@ -376,7 +376,7 @@
      * @return year
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getYear(final Object self) {
+    public static double getYear(final Object self) {
         final NativeDate nd = getNativeDate(self);
         return (nd != null && nd.isValidDate()) ? (yearFromTime(nd.getLocalTime()) - 1900) : Double.NaN;
     }
@@ -388,7 +388,7 @@
      * @return month
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getMonth(final Object self) {
+    public static double getMonth(final Object self) {
         return getField(self, MONTH);
     }
 
@@ -399,7 +399,7 @@
      * @return UTC month
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCMonth(final Object self) {
+    public static double getUTCMonth(final Object self) {
         return getUTCField(self, MONTH);
     }
 
@@ -410,7 +410,7 @@
      * @return date
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getDate(final Object self) {
+    public static double getDate(final Object self) {
         return getField(self, DAY);
     }
 
@@ -421,7 +421,7 @@
      * @return UTC Date
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCDate(final Object self) {
+    public static double getUTCDate(final Object self) {
         return getUTCField(self, DAY);
     }
 
@@ -432,7 +432,7 @@
      * @return day
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getDay(final Object self) {
+    public static double getDay(final Object self) {
         final NativeDate nd = getNativeDate(self);
         return (nd != null && nd.isValidDate()) ? weekDay(nd.getLocalTime()) : Double.NaN;
     }
@@ -444,7 +444,7 @@
      * @return UTC day
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCDay(final Object self) {
+    public static double getUTCDay(final Object self) {
         final NativeDate nd = getNativeDate(self);
         return (nd != null && nd.isValidDate()) ? weekDay(nd.getTime()) : Double.NaN;
     }
@@ -456,7 +456,7 @@
      * @return hours
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getHours(final Object self) {
+    public static double getHours(final Object self) {
         return getField(self, HOUR);
     }
 
@@ -467,7 +467,7 @@
      * @return UTC hours
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCHours(final Object self) {
+    public static double getUTCHours(final Object self) {
         return getUTCField(self, HOUR);
     }
 
@@ -478,7 +478,7 @@
      * @return minutes
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getMinutes(final Object self) {
+    public static double getMinutes(final Object self) {
         return getField(self, MINUTE);
     }
 
@@ -489,7 +489,7 @@
      * @return UTC minutes
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCMinutes(final Object self) {
+    public static double getUTCMinutes(final Object self) {
         return getUTCField(self, MINUTE);
     }
 
@@ -500,7 +500,7 @@
      * @return seconds
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getSeconds(final Object self) {
+    public static double getSeconds(final Object self) {
         return getField(self, SECOND);
     }
 
@@ -511,7 +511,7 @@
      * @return UTC seconds
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCSeconds(final Object self) {
+    public static double getUTCSeconds(final Object self) {
         return getUTCField(self, SECOND);
     }
 
@@ -522,7 +522,7 @@
      * @return milliseconds
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getMilliseconds(final Object self) {
+    public static double getMilliseconds(final Object self) {
         return getField(self, MILLISECOND);
     }
 
@@ -533,7 +533,7 @@
      * @return UTC milliseconds
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getUTCMilliseconds(final Object self) {
+    public static double getUTCMilliseconds(final Object self) {
         return getUTCField(self, MILLISECOND);
     }
 
@@ -544,7 +544,7 @@
      * @return time zone offset or NaN if N/A
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object getTimezoneOffset(final Object self) {
+    public static double getTimezoneOffset(final Object self) {
         final NativeDate nd = getNativeDate(self);
         if (nd != null && nd.isValidDate()) {
             final long msec = (long) nd.getTime();
@@ -561,7 +561,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object setTime(final Object self, final Object time) {
+    public static double setTime(final Object self, final Object time) {
         final NativeDate nd  = getNativeDate(self);
         final double     num = timeClip(JSType.toNumber(time));
         nd.setTime(num);
@@ -576,7 +576,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object setMilliseconds(final Object self, final Object... args) {
+    public static double setMilliseconds(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, MILLISECOND, args, true);
         return nd.getTime();
@@ -590,7 +590,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object setUTCMilliseconds(final Object self, final Object... args) {
+    public static double setUTCMilliseconds(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, MILLISECOND, args, false);
         return nd.getTime();
@@ -604,7 +604,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
-    public static Object setSeconds(final Object self, final Object... args) {
+    public static double setSeconds(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, SECOND, args, true);
         return nd.getTime();
@@ -618,7 +618,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
-    public static Object setUTCSeconds(final Object self, final Object... args) {
+    public static double setUTCSeconds(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, SECOND, args, false);
         return nd.getTime();
@@ -632,7 +632,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
-    public static Object setMinutes(final Object self, final Object... args) {
+    public static double setMinutes(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, MINUTE, args, true);
         return nd.getTime();
@@ -646,7 +646,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
-    public static Object setUTCMinutes(final Object self, final Object... args) {
+    public static double setUTCMinutes(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, MINUTE, args, false);
         return nd.getTime();
@@ -660,7 +660,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
-    public static Object setHours(final Object self, final Object... args) {
+    public static double setHours(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, HOUR, args, true);
         return nd.getTime();
@@ -674,7 +674,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
-    public static Object setUTCHours(final Object self, final Object... args) {
+    public static double setUTCHours(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, HOUR, args, false);
         return nd.getTime();
@@ -688,7 +688,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object setDate(final Object self, final Object... args) {
+    public static double setDate(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, DAY, args, true);
         return nd.getTime();
@@ -702,7 +702,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object setUTCDate(final Object self, final Object... args) {
+    public static double setUTCDate(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, DAY, args, false);
         return nd.getTime();
@@ -716,7 +716,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
-    public static Object setMonth(final Object self, final Object... args) {
+    public static double setMonth(final Object self, final Object... args) {
         final NativeDate nd = getNativeDate(self);
         setFields(nd, MONTH, args, true);
         return nd.getTime();
@@ -730,7 +730,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
-    public static Object setUTCMonth(final Object self, final Object... args) {
+    public static double setUTCMonth(final Object self, final Object... args) {
         final NativeDate nd = ensureNativeDate(self);
         setFields(nd, MONTH, args, false);
         return nd.getTime();
@@ -744,7 +744,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
-    public static Object setFullYear(final Object self, final Object... args) {
+    public static double setFullYear(final Object self, final Object... args) {
         final NativeDate nd   = ensureNativeDate(self);
         if (nd.isValidDate()) {
             setFields(nd, YEAR, args, true);
@@ -767,7 +767,7 @@
      * @return time
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
-    public static Object setUTCFullYear(final Object self, final Object... args) {
+    public static double setUTCFullYear(final Object self, final Object... args) {
         final NativeDate nd   = ensureNativeDate(self);
         if (nd.isValidDate()) {
             setFields(nd, YEAR, args, false);
@@ -786,7 +786,7 @@
      * @return NativeDate
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object setYear(final Object self, final Object year) {
+    public static double setYear(final Object self, final Object year) {
         final NativeDate nd = getNativeDate(self);
         if (isNaN(nd.getTime())) {
             nd.setTime(utc(0, nd.getTimeZone()));
@@ -813,7 +813,7 @@
      * @return string representation of date
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toUTCString(final Object self) {
+    public static String toUTCString(final Object self) {
         return toGMTStringImpl(self);
     }
 
@@ -826,7 +826,7 @@
      * @return string representation of date
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toGMTString(final Object self) {
+    public static String toGMTString(final Object self) {
         return toGMTStringImpl(self);
     }
 
@@ -837,7 +837,7 @@
      * @return string representation of date
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toISOString(final Object self) {
+    public static String toISOString(final Object self) {
         return toISOStringImpl(self);
     }
 
@@ -1282,14 +1282,14 @@
         }
     }
 
-    private static Object getField(final Object self, final int field) {
+    private static double getField(final Object self, final int field) {
         final NativeDate nd = getNativeDate(self);
-        return (nd != null && nd.isValidDate()) ? valueFromTime(field, nd.getLocalTime()) : Double.NaN;
+        return (nd != null && nd.isValidDate()) ? (double)valueFromTime(field, nd.getLocalTime()) : Double.NaN;
     }
 
-    private static Object getUTCField(final Object self, final int field) {
+    private static double getUTCField(final Object self, final int field) {
         final NativeDate nd = getNativeDate(self);
-        return (nd != null && nd.isValidDate()) ? valueFromTime(field, nd.getTime()) : Double.NaN;
+        return (nd != null && nd.isValidDate()) ? (double)valueFromTime(field, nd.getTime()) : Double.NaN;
     }
 
     private static void setFields(final NativeDate nd, final int fieldId, final Object[] args, final boolean local) {
@@ -1344,5 +1344,4 @@
     private TimeZone getTimeZone() {
         return timezone;
     }
-
 }
--- a/src/jdk/nashorn/internal/objects/NativeDebug.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeDebug.java	Wed May 28 16:53:43 2014 +0200
@@ -30,7 +30,6 @@
 import java.io.PrintWriter;
 import java.util.LinkedList;
 import java.util.Objects;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -105,7 +104,7 @@
      * @return true if reference identity
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object identical(final Object self, final Object obj1, final Object obj2) {
+    public static boolean identical(final Object self, final Object obj1, final Object obj2) {
         return obj1 == obj2;
     }
 
@@ -158,7 +157,7 @@
      * @return return {@link Object#equals(Object)} for objects.
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object equals(final Object self, final Object obj1, final Object obj2) {
+    public static boolean equals(final Object self, final Object obj1, final Object obj2) {
         return Objects.equals(obj1, obj2);
     }
 
@@ -170,7 +169,7 @@
      * @return Java string representation of {@code obj}
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object toJavaString(final Object self, final Object obj) {
+    public static String toJavaString(final Object self, final Object obj) {
         return Objects.toString(obj);
     }
 
@@ -182,7 +181,7 @@
      * @return string representation
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object toIdentString(final Object self, final Object obj) {
+    public static String toIdentString(final Object self, final Object obj) {
         if (obj == null) {
             return "null";
         }
@@ -199,7 +198,7 @@
      * @return listener count
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object getListenerCount(final Object self, final Object obj) {
+    public static int getListenerCount(final Object self, final Object obj) {
         return (obj instanceof ScriptObject) ? PropertyListeners.getListenerCount((ScriptObject) obj) : 0;
     }
 
@@ -334,7 +333,7 @@
      * @return array of events
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static RuntimeEvent<?>[] getRuntimeEvents(final Object self) {
+    public static Object getRuntimeEvents(final Object self) {
         final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
         return q.toArray(new RuntimeEvent<?>[q.size()]);
     }
@@ -345,7 +344,7 @@
      * @return the freshest event, null if queue is empty
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static RuntimeEvent<?> getLastRuntimeEvent(final Object self) {
+    public static Object getLastRuntimeEvent(final Object self) {
         final LinkedList<RuntimeEvent<?>> q = getEventQueue(self);
         return q.isEmpty() ? null : q.getLast();
     }
--- a/src/jdk/nashorn/internal/objects/NativeError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeError.java	Wed May 28 16:53:43 2014 +0200
@@ -126,7 +126,7 @@
      * @return NativeError instance
      */
     @Constructor
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeError(msg);
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeEvalError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeEvalError.java	Wed May 28 16:53:43 2014 +0200
@@ -98,7 +98,7 @@
      * @return new EvalError
      */
     @Constructor(name = "EvalError")
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeEvalError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeEvalError(msg);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeFloat32Array.java	Wed May 28 16:53:43 2014 +0200
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
 import java.nio.FloatBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -174,8 +173,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeFloat32Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeFloat32Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeFloat32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -225,8 +224,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeFloat32Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeFloat32Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeFloat64Array.java	Wed May 28 16:53:43 2014 +0200
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
 import java.nio.DoubleBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -174,8 +173,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeFloat64Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeFloat64Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeFloat64Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -225,8 +224,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeFloat64Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeFloat64Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeFunction.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeFunction.java	Wed May 28 16:53:43 2014 +0200
@@ -28,6 +28,7 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -47,7 +48,6 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.Source;
 
 /**
  * ECMA 15.3 Function Objects
@@ -78,7 +78,7 @@
      * @return string representation of Function
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self) {
+    public static String toString(final Object self) {
         if (!(self instanceof ScriptFunction)) {
             throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
@@ -204,7 +204,7 @@
      * @return function with bound arguments
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object bind(final Object self, final Object... args) {
+    public static ScriptFunction bind(final Object self, final Object... args) {
         if (!(self instanceof ScriptFunction)) {
             throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
@@ -229,7 +229,7 @@
      * @return source for function
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toSource(final Object self) {
+    public static String toSource(final Object self) {
         if (!(self instanceof ScriptFunction)) {
             throw typeError("not.a.function", ScriptRuntime.safeToString(self));
         }
@@ -247,7 +247,7 @@
      * @return new NativeFunction
      */
     @Constructor(arity = 1)
-    public static Object function(final boolean newObj, final Object self, final Object... args) {
+    public static ScriptFunction function(final boolean newObj, final Object self, final Object... args) {
         final StringBuilder sb = new StringBuilder();
 
         sb.append("(function (");
@@ -283,13 +283,11 @@
 
         final Global global = Global.instance();
 
-        return Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext());
+        return (ScriptFunction)Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext());
     }
 
     private static void checkFunctionParameters(final String params) {
-        final Source            src    = new Source("<function>", params);
-        final ScriptEnvironment env    = Global.getEnv();
-        final Parser            parser = new Parser(env, src, new Context.ThrowErrorManager(), env._strict, null);
+        final Parser parser = getParser(params);
         try {
             parser.parseFormalParameterList();
         } catch (final ParserException pe) {
@@ -298,13 +296,16 @@
     }
 
     private static void checkFunctionBody(final String funcBody) {
-        final Source            src    = new Source("<function>", funcBody);
-        final ScriptEnvironment env    = Global.getEnv();
-        final Parser            parser = new Parser(env, src, new Context.ThrowErrorManager(), env._strict, null);
+        final Parser parser = getParser(funcBody);
         try {
             parser.parseFunctionBody();
         } catch (final ParserException pe) {
             pe.throwAsEcmaException();
         }
     }
+
+    private static Parser getParser(final String sourceText) {
+        final ScriptEnvironment env = Global.getEnv();
+        return new Parser(env, sourceFor("<function>", sourceText), new Context.ThrowErrorManager(), env._strict, null);
+    }
 }
--- a/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeInt16Array.java	Wed May 28 16:53:43 2014 +0200
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
 import java.nio.ShortBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -167,8 +166,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeInt16Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeInt16Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeInt16Array(final NativeArrayBuffer buffer, final int byteOffset, final int byteLength) {
@@ -213,8 +212,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeInt16Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeInt16Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeInt32Array.java	Wed May 28 16:53:43 2014 +0200
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -165,8 +164,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeInt32Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeInt32Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeInt32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -211,8 +210,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeInt32Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeInt32Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeInt8Array.java	Wed May 28 16:53:43 2014 +0200
@@ -30,7 +30,6 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -166,8 +165,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeInt8Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeInt8Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeInt8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -212,8 +211,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeInt8Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeInt8Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Wed May 28 16:53:43 2014 +0200
@@ -537,7 +537,7 @@
      * @return new NativeJSAdapter
      */
     @Constructor
-    public static Object construct(final boolean isNew, final Object self, final Object... args) {
+    public static NativeJSAdapter construct(final boolean isNew, final Object self, final Object... args) {
         Object proto     = UNDEFINED;
         Object overrides = UNDEFINED;
         Object adaptee;
--- a/src/jdk/nashorn/internal/objects/NativeJava.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeJava.java	Wed May 28 16:53:43 2014 +0200
@@ -75,7 +75,7 @@
      * @see #type(Object, Object)
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object isType(final Object self, final Object type) {
+    public static boolean isType(final Object self, final Object type) {
         return type instanceof StaticClass;
     }
 
@@ -338,7 +338,7 @@
      * null.
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object from(final Object self, final Object objArray) {
+    public static NativeArray from(final Object self, final Object objArray) {
         if (objArray == null) {
             return null;
         } else if (objArray instanceof Collection) {
--- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Wed May 28 16:53:43 2014 +0200
@@ -89,7 +89,7 @@
      * @return NativeJavaImporter instance
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean isNew, final Object self, final Object... args) {
+    public static NativeJavaImporter constructor(final boolean isNew, final Object self, final Object... args) {
         return new NativeJavaImporter(args);
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeNumber.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeNumber.java	Wed May 28 16:53:43 2014 +0200
@@ -156,7 +156,7 @@
      * @return number in decimal fixed point notation
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toFixed(final Object self, final Object fractionDigits) {
+    public static String toFixed(final Object self, final Object fractionDigits) {
         return toFixed(self, JSType.toInteger(fractionDigits));
     }
 
@@ -169,7 +169,7 @@
      * @return number in decimal fixed point notation
      */
     @SpecializedFunction
-    public static Object toFixed(final Object self, final int fractionDigits) {
+    public static String toFixed(final Object self, final int fractionDigits) {
         if (fractionDigits < 0 || fractionDigits > 20) {
             throw rangeError("invalid.fraction.digits", "toFixed");
         }
@@ -200,7 +200,7 @@
      * @return number in decimal exponential notation
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toExponential(final Object self, final Object fractionDigits) {
+    public static String toExponential(final Object self, final Object fractionDigits) {
         final double  x         = getNumberValue(self);
         final boolean trimZeros = fractionDigits == UNDEFINED;
         final int     f         = trimZeros ? 16 : JSType.toInteger(fractionDigits);
@@ -228,7 +228,7 @@
      * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toPrecision(final Object self, final Object precision) {
+    public static String toPrecision(final Object self, final Object precision) {
         final double x = getNumberValue(self);
         if (precision == UNDEFINED) {
             return JSType.toString(x);
@@ -245,11 +245,11 @@
      * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
      */
     @SpecializedFunction
-    public static Object toPrecision(Object self, final int precision) {
+    public static String toPrecision(Object self, final int precision) {
         return toPrecision(getNumberValue(self), precision);
     }
 
-    private static Object toPrecision(final double x, final int p) {
+    private static String toPrecision(final double x, final int p) {
         if (Double.isNaN(x)) {
             return "NaN";
         } else if (Double.isInfinite(x)) {
@@ -276,7 +276,7 @@
      * @return string representation of this Number in the given radix
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self, final Object radix) {
+    public static String toString(final Object self, final Object radix) {
         if (radix != UNDEFINED) {
             final int intRadix = JSType.toInteger(radix);
             if (intRadix != 10) {
@@ -297,7 +297,7 @@
      * @return localized string for this Number
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleString(final Object self) {
+    public static String toLocaleString(final Object self) {
         return JSType.toString(getNumberValue(self));
     }
 
@@ -306,10 +306,10 @@
      * ECMA 15.7.4.4 Number.prototype.valueOf ( )
      *
      * @param self self reference
-     * @return boxed number value for this Number
+     * @return number value for this Number
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object valueOf(final Object self) {
+    public static double valueOf(final Object self) {
         return getNumberValue(self);
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeObject.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Wed May 28 16:53:43 2014 +0200
@@ -111,7 +111,7 @@
      * @return the 'obj' object
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
+    public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
         Global.checkObject(obj);
         final ScriptObject sobj = (ScriptObject)obj;
         if (buf instanceof ByteBuffer) {
@@ -203,7 +203,7 @@
      * @return array of property names
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object getOwnPropertyNames(final Object self, final Object obj) {
+    public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
         } else if (obj instanceof ScriptObjectMirror) {
@@ -222,7 +222,7 @@
      * @return object created
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object create(final Object self, final Object proto, final Object props) {
+    public static ScriptObject create(final Object self, final Object proto, final Object props) {
         if (proto != null) {
             Global.checkObject(proto);
         }
@@ -248,9 +248,10 @@
      * @return object
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
-        Global.checkObject(obj).defineOwnProperty(JSType.toString(prop), attr, true);
-        return obj;
+    public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
+        final ScriptObject sobj = Global.checkObject(obj);
+        sobj.defineOwnProperty(JSType.toString(prop), attr, true);
+        return sobj;
     }
 
     /**
@@ -262,7 +263,7 @@
      * @return object
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object defineProperties(final Object self, final Object obj, final Object props) {
+    public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
         final ScriptObject sobj     = Global.checkObject(obj);
         final Object       propsObj = Global.toObject(props);
 
@@ -339,7 +340,7 @@
      * @return true if sealed, false otherwise
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object isSealed(final Object self, final Object obj) {
+    public static boolean isSealed(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).isSealed();
         } else if (obj instanceof ScriptObjectMirror) {
@@ -357,7 +358,7 @@
      * @return true if object is frozen, false otherwise
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object isFrozen(final Object self, final Object obj) {
+    public static boolean isFrozen(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).isFrozen();
         } else if (obj instanceof ScriptObjectMirror) {
@@ -375,7 +376,7 @@
      * @return true if object is extensible, false otherwise
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object isExtensible(final Object self, final Object obj) {
+    public static boolean isExtensible(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).isExtensible();
         } else if (obj instanceof ScriptObjectMirror) {
@@ -393,7 +394,7 @@
      * @return array of keys in object
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
-    public static Object keys(final Object self, final Object obj) {
+    public static ScriptObject keys(final Object self, final Object obj) {
         if (obj instanceof ScriptObject) {
             final ScriptObject sobj = (ScriptObject)obj;
             return new NativeArray(sobj.getOwnKeys(false));
@@ -449,7 +450,7 @@
      * @return ToString of object
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self) {
+    public static String toString(final Object self) {
         return ScriptRuntime.builtinObjectToString(self);
     }
 
@@ -502,7 +503,7 @@
      * @return true if property exists in object
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object hasOwnProperty(final Object self, final Object v) {
+    public static boolean hasOwnProperty(final Object self, final Object v) {
         // Convert ScriptObjects to primitive with String.class hint
         // but no need to convert other primitives to string.
         final Object key = JSType.toPrimitive(v, String.class);
@@ -519,7 +520,7 @@
      * @return true if object is prototype of v
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object isPrototypeOf(final Object self, final Object v) {
+    public static boolean isPrototypeOf(final Object self, final Object v) {
         if (!(v instanceof ScriptObject)) {
             return false;
         }
@@ -545,7 +546,7 @@
      * @return true if property is enumerable
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object propertyIsEnumerable(final Object self, final Object v) {
+    public static boolean propertyIsEnumerable(final Object self, final Object v) {
         final String str = JSType.toString(v);
         final Object obj = Global.toObject(self);
 
--- a/src/jdk/nashorn/internal/objects/NativeRangeError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeRangeError.java	Wed May 28 16:53:43 2014 +0200
@@ -98,7 +98,7 @@
      * @return new RangeError
      */
     @Constructor(name = "RangeError")
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeRangeError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeRangeError(msg);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Wed May 28 16:53:43 2014 +0200
@@ -98,7 +98,7 @@
      * @return new ReferenceError
      */
     @Constructor(name = "ReferenceError")
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeReferenceError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeReferenceError(msg);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeRegExp.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java	Wed May 28 16:53:43 2014 +0200
@@ -124,7 +124,7 @@
      * @return new NativeRegExp
      */
     @Constructor(arity = 2)
-    public static Object constructor(final boolean isNew, final Object self, final Object... args) {
+    public static NativeRegExp constructor(final boolean isNew, final Object self, final Object... args) {
         if (args.length > 1) {
             return newRegExp(args[0], args[1]);
         } else if (args.length > 0) {
@@ -144,7 +144,7 @@
      * @return new NativeRegExp
      */
     @SpecializedConstructor
-    public static Object constructor(final boolean isNew, final Object self) {
+    public static NativeRegExp constructor(final boolean isNew, final Object self) {
         return new NativeRegExp("", "");
     }
 
@@ -159,7 +159,7 @@
      * @return new NativeRegExp
      */
     @SpecializedConstructor
-    public static Object constructor(final boolean isNew, final Object self, final Object pattern) {
+    public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern) {
         return newRegExp(pattern, UNDEFINED);
     }
 
@@ -175,7 +175,7 @@
      * @return new NativeRegExp
      */
     @SpecializedConstructor
-    public static Object constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
+    public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
         return newRegExp(pattern, flags);
     }
 
@@ -285,7 +285,7 @@
      * @return new NativeRegExp
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object compile(final Object self, final Object pattern, final Object flags) {
+    public static ScriptObject compile(final Object self, final Object pattern, final Object flags) {
         final NativeRegExp regExp   = checkRegExp(self);
         final NativeRegExp compiled = newRegExp(pattern, flags);
         // copy over regexp to 'self'
@@ -304,7 +304,7 @@
      * @return array containing the matches or {@code null} if no match
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object exec(final Object self, final Object string) {
+    public static ScriptObject exec(final Object self, final Object string) {
         return checkRegExp(self).exec(JSType.toString(string));
     }
 
@@ -316,7 +316,7 @@
      * @return true if matches found, false otherwise
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object test(final Object self, final Object string) {
+    public static boolean test(final Object self, final Object string) {
         return checkRegExp(self).test(JSType.toString(string));
     }
 
@@ -327,7 +327,7 @@
      * @return string version of regexp
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self) {
+    public static String toString(final Object self) {
         return checkRegExp(self).toString();
     }
 
@@ -620,7 +620,7 @@
      * @param string String to match.
      * @return NativeArray of matches, string or null.
      */
-    public Object exec(final String string) {
+    public NativeRegExpExecResult exec(final String string) {
         final RegExpResult match = execInner(string);
 
         if (match == null) {
@@ -637,7 +637,7 @@
      * @param string String to match.
      * @return True if a match is found.
      */
-    public Object test(final String string) {
+    public boolean test(final String string) {
         return execInner(string) != null;
     }
 
@@ -651,7 +651,7 @@
      * @param replacement Replacement string.
      * @return String with substitutions.
      */
-    Object replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
+    String replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
         final RegExpMatcher matcher = regexp.match(string);
 
         if (matcher == null) {
@@ -820,7 +820,7 @@
      * @param limit  Split limit.
      * @return Array of substrings.
      */
-    Object split(final String string, final long limit) {
+    NativeArray split(final String string, final long limit) {
         if (limit == 0L) {
             return new NativeArray();
         }
@@ -883,7 +883,7 @@
      * @param string String to match.
      * @return Index of match.
      */
-    Object search(final String string) {
+    int search(final String string) {
         final RegExpResult match = execInner(string);
 
         if (match == null) {
--- a/src/jdk/nashorn/internal/objects/NativeString.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeString.java	Wed May 28 16:53:43 2014 +0200
@@ -424,7 +424,7 @@
      * @return string with arguments translated to charcodes
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1, where = Where.CONSTRUCTOR)
-    public static Object fromCharCode(final Object self, final Object... args) {
+    public static String fromCharCode(final Object self, final Object... args) {
         final char[] buf = new char[args.length];
         int index = 0;
         for (final Object arg : args) {
@@ -454,7 +454,7 @@
      * @return string with one charcode
      */
     @SpecializedFunction
-    public static Object fromCharCode(final Object self, final int value) {
+    public static String fromCharCode(final Object self, final int value) {
         return Character.toString((char)(value & 0xffff));
     }
 
@@ -493,7 +493,7 @@
      * @return string with one charcode
      */
     @SpecializedFunction
-    public static Object fromCharCode(final Object self, final int ch1, final int ch2, final int ch3, final int ch4) {
+    public static String fromCharCode(final Object self, final int ch1, final int ch2, final int ch3, final int ch4) {
         return Character.toString((char)(ch1 & 0xffff)) + Character.toString((char)(ch2 & 0xffff)) + Character.toString((char)(ch3 & 0xffff)) + Character.toString((char)(ch4 & 0xffff));
     }
 
@@ -504,7 +504,7 @@
      * @return string with one charcode
      */
     @SpecializedFunction
-    public static Object fromCharCode(final Object self, final double value) {
+    public static String fromCharCode(final Object self, final double value) {
         return Character.toString((char)JSType.toUint16(value));
     }
 
@@ -514,7 +514,7 @@
      * @return self as string
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toString(final Object self) {
+    public static String toString(final Object self) {
         return getString(self);
     }
 
@@ -524,7 +524,7 @@
      * @return self as string
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object valueOf(final Object self) {
+    public static String valueOf(final Object self) {
         return getString(self);
     }
 
@@ -535,7 +535,7 @@
      * @return string representing the char at the given position
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object charAt(final Object self, final Object pos) {
+    public static String charAt(final Object self, final Object pos) {
         return charAtImpl(checkObjectToString(self), JSType.toInteger(pos));
     }
 
@@ -572,7 +572,7 @@
      * @return number representing charcode at position
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object charCodeAt(final Object self, final Object pos) {
+    public static double charCodeAt(final Object self, final Object pos) {
         return charCodeAtImpl(checkObjectToString(self), JSType.toInteger(pos));
     }
 
@@ -627,7 +627,7 @@
      * @return position of first match or -1
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object indexOf(final Object self, final Object search, final Object pos) {
+    public static int indexOf(final Object self, final Object search, final Object pos) {
         final String str = checkObjectToString(self);
         return str.indexOf(JSType.toString(search), JSType.toInteger(pos));
     }
@@ -675,7 +675,7 @@
      * @return last position of match or -1
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
-    public static Object lastIndexOf(final Object self, final Object search, final Object pos) {
+    public static int lastIndexOf(final Object self, final Object search, final Object pos) {
 
         final String str       = checkObjectToString(self);
         final String searchStr = JSType.toString(search);
@@ -706,7 +706,7 @@
      * @return result of locale sensitive comparison operation between {@code self} and {@code that}
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object localeCompare(final Object self, final Object that) {
+    public static double localeCompare(final Object self, final Object that) {
 
         final String   str      = checkObjectToString(self);
         final Collator collator = Collator.getInstance(Global.getEnv()._locale);
@@ -714,7 +714,7 @@
         collator.setStrength(Collator.IDENTICAL);
         collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
 
-        return (double)collator.compare(str, JSType.toString(that));
+        return collator.compare(str, JSType.toString(that));
     }
 
     /**
@@ -724,7 +724,7 @@
      * @return array of regexp matches
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object match(final Object self, final Object regexp) {
+    public static ScriptObject match(final Object self, final Object regexp) {
 
         final String str = checkObjectToString(self);
 
@@ -772,7 +772,7 @@
      * @throws Throwable if replacement fails
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object replace(final Object self, final Object string, final Object replacement) throws Throwable {
+    public static String replace(final Object self, final Object string, final Object replacement) throws Throwable {
 
         final String str = checkObjectToString(self);
 
@@ -798,7 +798,7 @@
      * @return offset where match occurred
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object search(final Object self, final Object string) {
+    public static int search(final Object self, final Object string) {
 
         final String       str          = checkObjectToString(self);
         final NativeRegExp nativeRegExp = Global.toRegExp(string == UNDEFINED ? "" : string);
@@ -815,7 +815,7 @@
      * @return sliced out substring
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object slice(final Object self, final Object start, final Object end) {
+    public static String slice(final Object self, final Object start, final Object end) {
 
         final String str      = checkObjectToString(self);
         if (end == UNDEFINED) {
@@ -832,7 +832,7 @@
      * @return sliced out substring
      */
     @SpecializedFunction
-    public static Object slice(final Object self, final int start) {
+    public static String slice(final Object self, final int start) {
         final String str = checkObjectToString(self);
         final int from = start < 0 ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
 
@@ -847,7 +847,7 @@
      * @return sliced out substring
      */
     @SpecializedFunction
-    public static Object slice(final Object self, final double start) {
+    public static String slice(final Object self, final double start) {
         return slice(self, (int)start);
     }
 
@@ -860,7 +860,7 @@
      * @return sliced out substring
      */
     @SpecializedFunction
-    public static Object slice(final Object self, final int start, final int end) {
+    public static String slice(final Object self, final int start, final int end) {
 
         final String str = checkObjectToString(self);
         final int len    = str.length();
@@ -880,7 +880,7 @@
      * @return sliced out substring
      */
     @SpecializedFunction
-    public static Object slice(final Object self, final double start, final double end) {
+    public static String slice(final Object self, final double start, final double end) {
         return slice(self, (int)start, (int)end);
     }
 
@@ -893,7 +893,7 @@
      * @return array object in which splits have been placed
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object split(final Object self, final Object separator, final Object limit) {
+    public static ScriptObject split(final Object self, final Object separator, final Object limit) {
         final String str = checkObjectToString(self);
         final long lim = limit == UNDEFINED ? JSType.MAX_UINT : JSType.toUint32(limit);
 
@@ -909,7 +909,7 @@
         return splitString(str, JSType.toString(separator), lim);
     }
 
-    private static Object splitString(String str, String separator, long limit) {
+    private static ScriptObject splitString(String str, String separator, long limit) {
         if (separator.isEmpty()) {
             final int length = (int) Math.min(str.length(), limit);
             final Object[] array = new Object[length];
@@ -950,7 +950,7 @@
      * @return substring given start and length of section
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object substr(final Object self, final Object start, final Object length) {
+    public static String substr(final Object self, final Object start, final Object length) {
         final String str       = JSType.toString(self);
         final int    strLength = str.length();
 
@@ -973,7 +973,7 @@
      * @return substring given start and end indexes
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object substring(final Object self, final Object start, final Object end) {
+    public static String substring(final Object self, final Object start, final Object end) {
 
         final String str = checkObjectToString(self);
         if (end == UNDEFINED) {
@@ -1053,7 +1053,7 @@
      * @return string to lower case
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLowerCase(final Object self) {
+    public static String toLowerCase(final Object self) {
         return checkObjectToString(self).toLowerCase(Locale.ROOT);
     }
 
@@ -1063,7 +1063,7 @@
      * @return string to locale sensitive lower case
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleLowerCase(final Object self) {
+    public static String toLocaleLowerCase(final Object self) {
         return checkObjectToString(self).toLowerCase(Global.getEnv()._locale);
     }
 
@@ -1073,7 +1073,7 @@
      * @return string to upper case
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toUpperCase(final Object self) {
+    public static String toUpperCase(final Object self) {
         return checkObjectToString(self).toUpperCase(Locale.ROOT);
     }
 
@@ -1083,7 +1083,7 @@
      * @return string to locale sensitive upper case
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object toLocaleUpperCase(final Object self) {
+    public static String toLocaleUpperCase(final Object self) {
         return checkObjectToString(self).toUpperCase(Global.getEnv()._locale);
     }
 
@@ -1093,7 +1093,7 @@
      * @return string trimmed from whitespace
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object trim(final Object self) {
+    public static String trim(final Object self) {
 
         final String str = checkObjectToString(self);
         int start = 0;
@@ -1115,7 +1115,7 @@
      * @return string trimmed left from whitespace
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object trimLeft(final Object self) {
+    public static String trimLeft(final Object self) {
 
         final String str = checkObjectToString(self);
         int start = 0;
@@ -1134,7 +1134,7 @@
      * @return string trimmed right from whitespace
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    public static Object trimRight(final Object self) {
+    public static String trimRight(final Object self) {
 
         final String str = checkObjectToString(self);
         final int start = 0;
@@ -1147,7 +1147,7 @@
         return str.substring(start, end + 1);
     }
 
-    private static Object newObj(final CharSequence str) {
+    private static ScriptObject newObj(final CharSequence str) {
         return new NativeString(str);
     }
 
--- a/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Wed May 28 16:53:43 2014 +0200
@@ -94,7 +94,7 @@
      * @return new SyntaxError
      */
     @Constructor(name = "SyntaxError")
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeSyntaxError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeSyntaxError(msg);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeTypeError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeTypeError.java	Wed May 28 16:53:43 2014 +0200
@@ -94,7 +94,7 @@
      * @return new TypeError
      */
     @Constructor(name = "TypeError")
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeTypeError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeTypeError(msg);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeURIError.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeURIError.java	Wed May 28 16:53:43 2014 +0200
@@ -93,7 +93,7 @@
      * @return new URIError
      */
     @Constructor(name = "URIError")
-    public static Object constructor(final boolean newObj, final Object self, final Object msg) {
+    public static NativeURIError constructor(final boolean newObj, final Object self, final Object msg) {
         return new NativeURIError(msg);
     }
 }
--- a/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeUint16Array.java	Wed May 28 16:53:43 2014 +0200
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -171,8 +170,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeUint16Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeUint16Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeUint16Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -217,8 +216,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeUint16Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeUint16Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeUint32Array.java	Wed May 28 16:53:43 2014 +0200
@@ -32,7 +32,6 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.IntBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -180,8 +179,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeUint32Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeUint32Array)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeUint32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -226,8 +225,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeUint32Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeUint32Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeUint8Array.java	Wed May 28 16:53:43 2014 +0200
@@ -30,7 +30,6 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -172,12 +171,12 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeUint8Array constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeUint8Array)constructorImpl(newObj, args, FACTORY);
     }
 
-    NativeUint8Array(NativeArrayBuffer buffer, int byteOffset, int elementLength) {
-        super(buffer, byteOffset, elementLength);
+    NativeUint8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
+        super(buffer, byteOffset, length);
     }
 
     @Override
@@ -218,8 +217,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeUint8Array subarray(final Object self, final Object begin, final Object end) {
+        return (NativeUint8Array)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java	Wed May 28 16:53:43 2014 +0200
@@ -25,14 +25,13 @@
 
 package jdk.nashorn.internal.objects;
 
+import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
-import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
-
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -82,6 +81,7 @@
         private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "getElem", int.class, int.class).methodHandle();
         private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
         private static final MethodHandle RINT     = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", double.class, double.class).methodHandle();
+        private static final MethodHandle CLAMP_LONG = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "clampLong", long.class, long.class).methodHandle();
 
         private Uint8ClampedArrayData(final ByteBuffer nb, final int start, final int end) {
             super(((ByteBuffer)nb.position(start).limit(end)).slice(), end - start);
@@ -108,8 +108,12 @@
         @Override
         public MethodHandle getElementSetter(final Class<?> elementType) {
             final MethodHandle setter = super.getElementSetter(elementType); //getContinuousElementSetter(getClass(), setElem(), elementType);
-            if (setter != null && elementType == double.class) {
-                return MH.filterArguments(setter, 2, RINT);
+            if (setter != null) {
+                if (elementType == double.class) {
+                    return MH.filterArguments(setter, 2, RINT);
+                } else if (elementType == long.class) {
+                    return MH.filterArguments(setter, 2, CLAMP_LONG);
+                }
             }
             return setter;
         }
@@ -186,6 +190,15 @@
             return (int)Math.rint(rint);
         }
 
+        @SuppressWarnings("unused")
+        private static long clampLong(final long l) {
+            if(l < 0L) {
+                return 0L;
+            } else if(l > 0xffL) {
+                return 0xffL;
+            }
+            return l;
+        }
     }
 
     /**
@@ -198,8 +211,8 @@
      * @return new typed array
      */
     @Constructor(arity = 1)
-    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
-        return constructorImpl(newObj, args, FACTORY);
+    public static NativeUint8ClampedArray constructor(final boolean newObj, final Object self, final Object... args) {
+        return (NativeUint8ClampedArray)constructorImpl(newObj, args, FACTORY);
     }
 
     NativeUint8ClampedArray(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
@@ -244,8 +257,8 @@
      * @return sub array
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
-    protected static Object subarray(final Object self, final Object begin, final Object end) {
-        return ArrayBufferView.subarrayImpl(self, begin, end);
+    protected static NativeUint8ClampedArray subarray(final Object self, final Object begin, final Object end) {
+        return (NativeUint8ClampedArray)ArrayBufferView.subarrayImpl(self, begin, end);
     }
 
     @Override
--- a/src/jdk/nashorn/internal/parser/Parser.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/parser/Parser.java	Wed May 28 16:53:43 2014 +0200
@@ -33,6 +33,7 @@
 import static jdk.nashorn.internal.parser.TokenType.CATCH;
 import static jdk.nashorn.internal.parser.TokenType.COLON;
 import static jdk.nashorn.internal.parser.TokenType.COMMARIGHT;
+import static jdk.nashorn.internal.parser.TokenType.CONST;
 import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
 import static jdk.nashorn.internal.parser.TokenType.DECPREFIX;
 import static jdk.nashorn.internal.parser.TokenType.ELSE;
@@ -926,6 +927,11 @@
             expect(SEMICOLON);
             break;
         default:
+            if (env._const_as_var && type == CONST) {
+                variableStatement(true);
+                break;
+            }
+
             if (type == IDENT || isNonStrictModeIdent()) {
                 if (T(k + 1) == COLON) {
                     labelStatement();
@@ -1211,6 +1217,12 @@
             case SEMICOLON:
                 break;
             default:
+                if (env._const_as_var && type == CONST) {
+                    // Var statements captured in for outer block.
+                    vars = variableStatement(false);
+                    break;
+                }
+
                 final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
                 forNode = forNode.setInit(lc, expression);
                 break;
@@ -1801,9 +1813,11 @@
                 // ECMA 12.4.1 strict mode restrictions
                 verifyStrictIdent(exception, "catch argument");
 
-                // Check for conditional catch.
+                // Nashorn extension: catch clause can have optional
+                // condition. So, a single try can have more than one
+                // catch clause each with it's own condition.
                 final Expression ifExpression;
-                if (type == IF) {
+                if (!env._no_syntax_extensions && type == IF) {
                     next();
                     // Get the exception condition.
                     ifExpression = expression();
--- a/src/jdk/nashorn/internal/parser/TokenType.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/parser/TokenType.java	Wed May 28 16:53:43 2014 +0200
@@ -112,7 +112,7 @@
     CATCH          (KEYWORD,  "catch"),
 //  CHAR           (FUTURE,   "char"),
     CLASS          (FUTURE,   "class"),
-    CONST          (FUTURE,  "const"),
+    CONST          (KEYWORD,  "const"),
     CONTINUE       (KEYWORD,  "continue"),
     DEBUGGER       (KEYWORD,  "debugger"),
     DEFAULT        (KEYWORD,  "default"),
--- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed May 28 16:53:43 2014 +0200
@@ -37,6 +37,8 @@
 import static jdk.nashorn.internal.runtime.JSType.getNumberOfAccessorTypes;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.SwitchPoint;
@@ -60,6 +62,7 @@
     private static final SwitchPoint NO_CHANGE_CALLBACK = new SwitchPoint();
 
     private static final int NOOF_TYPES = getNumberOfAccessorTypes();
+    private static final long serialVersionUID = 3371720170182154920L;
 
     /**
      * Properties in different maps for the same structure class will share their field getters and setters. This could
@@ -133,16 +136,16 @@
     }
 
     /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
-    protected final MethodHandle primitiveGetter;
+    private transient MethodHandle primitiveGetter;
 
     /** Seed setter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
-    protected final MethodHandle primitiveSetter;
+    private transient MethodHandle primitiveSetter;
 
     /** Seed getter for the Object version of this field */
-    protected final MethodHandle objectGetter;
+    private transient MethodHandle objectGetter;
 
     /** Seed setter for the Object version of this field */
-    protected final MethodHandle objectSetter;
+    private transient MethodHandle objectSetter;
 
     /**
      * Current type of this object, in object only mode, this is an Object.class. In dual-fields mode
@@ -263,6 +266,11 @@
     public AccessorProperty(final String key, final int flags, final Class<?> structure, final int slot) {
         super(key, flags, slot);
 
+        initGetterSetter(structure);
+    }
+
+    private void initGetterSetter(final Class<?> structure) {
+        final int slot = getSlot();
         /*
          * primitiveGetter and primitiveSetter are only used in dual fields mode. Setting them to null also
          * works in dual field mode, it only means that the property never has a primitive
@@ -369,6 +377,12 @@
         setCurrentType(OBJECT_FIELDS_ONLY ? Object.class : null);
     }
 
+    private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        // Restore getters array
+        GETTER_CACHE = new MethodHandle[NOOF_TYPES];
+    }
+
     private static MethodHandle bindTo(final MethodHandle mh, final Object receiver) {
         if (mh == null) {
             return null;
@@ -516,6 +530,16 @@
     }
 
     @Override
+    void initMethodHandles(final Class<?> structure) {
+        if (!ScriptObject.class.isAssignableFrom(structure) || !StructureLoader.isStructureClass(structure.getName())) {
+            throw new IllegalArgumentException();
+        }
+        if (!isSpill()) {
+            initGetterSetter(structure);
+        }
+    }
+
+    @Override
     public MethodHandle getGetter(final Class<?> type) {
         final int i = getAccessorTypeIndex(type);
 
--- a/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Wed May 28 16:53:43 2014 +0200
@@ -25,6 +25,8 @@
 
 package jdk.nashorn.internal.runtime;
 
+import java.util.Collection;
+import java.util.Map;
 import jdk.nashorn.internal.codegen.ClassEmitter;
 
 /**
@@ -47,7 +49,7 @@
     public T getOwner();
 
     /**
-     * Install a class
+     * Install a class.
      * @param className name of the class with / separation
      * @param bytecode  bytecode
      * @return the installed class
@@ -55,6 +57,14 @@
     public Class<?> install(final String className, final byte[] bytecode);
 
     /**
+     * Initialize already installed classes.
+     * @param classes the class to initialize
+     * @param source the source object for the classes
+     * @param constants the runtime constants for the classes
+     */
+    public void initialize(final Collection<Class<?>> classes, final Source source, final Object[] constants);
+
+    /**
      * Verify generated bytecode before emission. This is called back from the
      * {@link ClassEmitter} or the {@link Compiler}. If the "--verify-code" parameter
      * hasn't been given, this is a nop
@@ -74,4 +84,13 @@
      * @return unique eval id
      */
     public long getUniqueEvalId();
+
+    /**
+     * Store a compiled script for later reuse
+     * @param source the script source
+     * @param mainClassName the main class name
+     * @param classBytes map of class names to class bytes
+     * @param constants constants array
+     */
+    public void storeCompiledScript(Source source, String mainClassName, Map<String, byte[]> classBytes, Object[] constants);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/runtime/CodeStore.java	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nashorn.internal.runtime;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Base64;
+import java.util.Map;
+
+/**
+ * A code cache for persistent caching of compiled scripts.
+ */
+final class CodeStore {
+
+    private final File dir;
+    private final int minSize;
+
+    // Message digest to file name encoder
+    private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
+
+    // Default minimum size for storing a compiled script class
+    private final static int DEFAULT_MIN_SIZE = 1000;
+
+    /**
+     * Constructor
+     * @param path directory to store code in
+     * @throws IOException
+     */
+    public CodeStore(final String path) throws IOException {
+        this(path, DEFAULT_MIN_SIZE);
+    }
+
+    /**
+     * Constructor
+     * @param path directory to store code in
+     * @param minSize minimum file size for caching scripts
+     * @throws IOException
+     */
+    public CodeStore(final String path, final int minSize) throws IOException {
+        this.dir = checkDirectory(path);
+        this.minSize = minSize;
+    }
+
+    private static File checkDirectory(final String path) throws IOException {
+        try {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
+                @Override
+                public File run() throws IOException {
+                    final File dir = new File(path).getAbsoluteFile();
+                    if (!dir.exists() && !dir.mkdirs()) {
+                        throw new IOException("Could not create directory: " + dir);
+                    } else if (!dir.isDirectory()) {
+                        throw new IOException("Not a directory: " + dir);
+                    } else if (!dir.canRead() || !dir.canWrite()) {
+                        throw new IOException("Directory not readable or writable: " + dir);
+                    }
+                    return dir;
+                }
+            });
+        } catch (PrivilegedActionException e) {
+            throw (IOException) e.getException();
+        }
+    }
+
+    /**
+     * Return a compiled script from the cache, or null if it isn't found.
+     *
+     * @param source the source
+     * @return the compiled script or null
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    public CompiledScript getScript(final Source source) throws IOException, ClassNotFoundException {
+        if (source.getLength() < minSize) {
+            return null;
+        }
+
+        final String digest = BASE64.encodeToString(source.getDigest());
+        final File file = new File(dir, digest);
+
+        try {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<CompiledScript>() {
+                @Override
+                public CompiledScript run() throws IOException, ClassNotFoundException {
+                    if (!file.exists()) {
+                        return null;
+                    }
+                    try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
+                        CompiledScript compiledScript = (CompiledScript) in.readObject();
+                        compiledScript.setSource(source);
+                        return compiledScript;
+                    }
+                }
+            });
+        } catch (PrivilegedActionException e) {
+            final Exception ex = e.getException();
+            if (ex instanceof IOException) {
+                throw  (IOException) ex;
+            } else if (ex instanceof ClassNotFoundException) {
+                throw (ClassNotFoundException) ex;
+            }
+            throw (new RuntimeException(ex));
+        }
+    }
+
+    /**
+     * Store a compiled script in the cache.
+     *
+     * @param source the source
+     * @param mainClassName the main class name
+     * @param classBytes a map of class bytes
+     * @param constants the constants array
+     * @throws IOException
+     */
+    public void putScript(final Source source, final String mainClassName, final Map<String, byte[]> classBytes, final Object[] constants)
+            throws IOException {
+        if (source.getLength() < minSize) {
+            return;
+        }
+        for (final Object constant : constants) {
+            // Make sure all constant data is serializable
+            if (! (constant instanceof Serializable)) {
+                return;
+            }
+        }
+
+        final String digest = BASE64.encodeToString(source.getDigest());
+        final File file = new File(dir, digest);
+        final CompiledScript script = new CompiledScript(source, mainClassName, classBytes, constants);
+
+        try {
+            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+                @Override
+                public Void run() throws IOException {
+                    try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
+                        out.writeObject(script);
+                    }
+                    return null;
+                }
+            });
+        } catch (PrivilegedActionException e) {
+             throw (IOException) e.getException();
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/runtime/CompiledScript.java	Wed May 28 16:53:43 2014 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nashorn.internal.runtime;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * Class representing a compiled script.
+ */
+final class CompiledScript implements Serializable {
+
+    /** Main class name. */
+    private final String mainClassName;
+
+    /** Map of class names to class bytes. */
+    private final Map<String, byte[]> classBytes;
+
+    /** Constants array. */
+    private final Object[] constants;
+
+    /** The source */
+    private transient Source source;
+
+    private static final long serialVersionUID = 2958227232195298340L;
+
+    /**
+     * Constructor.
+     *
+     * @param mainClassName main class name
+     * @param classBytes map of class names to class bytes
+     * @param constants constants array
+     */
+    CompiledScript(final Source source, final String mainClassName, final Map<String, byte[]> classBytes, final Object[] constants) {
+        this.source = source;
+        this.mainClassName = mainClassName;
+        this.classBytes = classBytes;
+        this.constants = constants;
+    }
+
+    /**
+     * Returns the main class name.
+     * @return the main class name
+     */
+    public String getMainClassName() {
+        return mainClassName;
+    }
+
+    /**
+     * Returns a map of class names to class bytes.
+     * @return map of class bytes
+     */
+    public Map<String, byte[]> getClassBytes() {
+        return classBytes;
+    }
+
+    /**
+     * Returns the constants array.
+     * @return constants array
+     */
+    public Object[] getConstants() {
+        return constants;
+    }
+
+    /**
+     * Returns the source of this cached script.
+     * @return the source
+     */
+    public Source getSource() {
+        return source;
+    }
+
+    /**
+     * Sets the source of this cached script.
+     * @param source the source
+     */
+    void setSource(final Source source) {
+        this.source = source;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = mainClassName.hashCode();
+        hash = 31 * hash + classBytes.hashCode();
+        hash = 31 * hash + Arrays.hashCode(constants);
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof CompiledScript)) {
+            return false;
+        }
+
+        final CompiledScript cs = (CompiledScript) obj;
+        return mainClassName.equals(cs.mainClassName)
+                && classBytes.equals(cs.classBytes)
+                && Arrays.equals(constants, cs.constants);
+    }
+}
--- a/src/jdk/nashorn/internal/runtime/Context.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/Context.java	Wed May 28 16:53:43 2014 +0200
@@ -25,10 +25,13 @@
 
 package jdk.nashorn.internal.runtime;
 
+import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
 import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
 import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
 
 import java.io.File;
 import java.io.IOException;
@@ -36,6 +39,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
@@ -46,14 +50,17 @@
 import java.security.CodeSource;
 import java.security.Permissions;
 import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.logging.Level;
-
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
@@ -70,8 +77,8 @@
 import jdk.nashorn.internal.runtime.logging.DebugLogger;
 import jdk.nashorn.internal.runtime.logging.Loggable;
 import jdk.nashorn.internal.runtime.logging.Logger;
+import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
 import jdk.nashorn.internal.runtime.options.Options;
-import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
 
 /**
  * This class manages the global state of execution. Context is immutable.
@@ -144,7 +151,42 @@
 
         @Override
         public Class<?> install(final String className, final byte[] bytecode) {
-            return loader.installClass(className, bytecode, codeSource);
+            final String   binaryName = Compiler.binaryName(className);
+            return loader.installClass(binaryName, bytecode, codeSource);
+        }
+
+        @Override
+        public void initialize(final Collection<Class<?>> classes, final Source source, final Object[] constants) {
+            // do these in parallel, this significantly reduces class installation overhead
+            // however - it still means that every thread needs a separate doPrivileged
+            classes.parallelStream().forEach(
+                new Consumer<Class<?>>() {
+                    @Override
+                    public void accept(final Class<?> clazz) {
+                        try {
+                            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+                                @Override
+                                public Void run() {
+                                    try {
+                                        //use reflection to write source and constants table to installed classes
+                                        final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
+                                        sourceField.setAccessible(true);
+                                        sourceField.set(null, source);
+
+                                        final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
+                                        constantsField.setAccessible(true);
+                                        constantsField.set(null, constants);
+                                    } catch (final IllegalAccessException | NoSuchFieldException e) {
+                                        throw new RuntimeException(e);
+                                    }
+                                    return null;
+                                }
+                            });
+                        } catch (final PrivilegedActionException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
         }
 
         @Override
@@ -161,6 +203,18 @@
         public long getUniqueEvalId() {
             return context.getUniqueEvalId();
         }
+
+        @Override
+        public void storeCompiledScript(final Source source, final String mainClassName,
+                                        final Map<String, byte[]> classBytes, final Object[] constants) {
+            if (context.codeStore != null) {
+                try {
+                    context.codeStore.putScript(source, mainClassName, classBytes, constants);
+                } catch (final IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
     }
 
     /** Is Context global debug mode enabled ? */
@@ -168,9 +222,12 @@
 
     private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
 
-    // class cache
+    // in-memory cache for loaded classes
     private ClassCache classCache;
 
+    // persistent code store
+    private CodeStore codeStore;
+
     /**
      * Get the current global scope
      * @return the current global scope
@@ -382,6 +439,19 @@
             classCache = new ClassCache(cacheSize);
         }
 
+        if (env._persistent_cache) {
+            if (env._lazy_compilation || ScriptEnvironment.globalOptimistic()) {
+                getErr().println("Can not use persistent class caching with lazy compilation or optimistic compilation.");
+            } else {
+                try {
+                    final String cacheDir = Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache");
+                    codeStore = new CodeStore(cacheDir);
+                } catch (final IOException e) {
+                    throw new RuntimeException("Error initializing code cache", e);
+                }
+            }
+        }
+
         // print version info if asked.
         if (env._version) {
             getErr().println("nashorn " + Version.version());
@@ -447,6 +517,37 @@
     }
 
     /**
+     * Interface to represent compiled code that can be re-used across many
+     * global scope instances
+     */
+    public static interface MultiGlobalCompiledScript {
+        /**
+         * Obtain script function object for a specific global scope object.
+         *
+         * @param newGlobal global scope for which function object is obtained
+         * @return script function for script level expressions
+         */
+        public ScriptFunction getFunction(final Global newGlobal);
+    }
+
+    /**
+     * Compile a top level script.
+     *
+     * @param source the script source
+     * @return reusable compiled script across many global scopes.
+     */
+    public MultiGlobalCompiledScript compileScript(final Source source) {
+        final Class<?> clazz = compile(source, this.errors, this._strict);
+
+        return new MultiGlobalCompiledScript() {
+            @Override
+            public ScriptFunction getFunction(final Global newGlobal) {
+                return getProgramFunction(clazz, newGlobal);
+            }
+        };
+    }
+
+    /**
      * Entry point for {@code eval}
      *
      * @param initialScope The scope of this eval call
@@ -459,7 +560,7 @@
      */
     public Object eval(final ScriptObject initialScope, final String string, final Object callThis, final Object location, final boolean strict) {
         final String  file       = location == UNDEFINED || location == null ? "<eval>" : location.toString();
-        final Source  source     = new Source(file, string);
+        final Source  source     = sourceFor(file, string);
         final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
         final Global  global = Context.getGlobal();
         ScriptObject scope = initialScope;
@@ -525,7 +626,7 @@
                         public Source run() {
                             try {
                                 final URL resURL = Context.class.getResource(resource);
-                                return resURL != null ? new Source(srcStr, resURL) : null;
+                                return resURL != null ? sourceFor(srcStr, resURL) : null;
                             } catch (final IOException exp) {
                                 return null;
                             }
@@ -557,7 +658,7 @@
             final String srcStr = (String)src;
             if (srcStr.startsWith(LOAD_CLASSPATH)) {
                 final URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length()));
-                source = url != null ? new Source(url.toString(), url) : null;
+                source = url != null ? sourceFor(url.toString(), url) : null;
             } else {
                 final File file = new File(srcStr);
                 if (srcStr.indexOf(':') != -1) {
@@ -570,31 +671,31 @@
                         } catch (final MalformedURLException e) {
                             url = file.toURI().toURL();
                         }
-                        source = new Source(url.toString(), url);
+                        source = sourceFor(url.toString(), url);
                     }
                 } else if (file.isFile()) {
-                    source = new Source(srcStr, file);
+                    source = sourceFor(srcStr, file);
                 }
             }
         } else if (src instanceof File && ((File)src).isFile()) {
             final File file = (File)src;
-            source = new Source(file.getName(), file);
+            source = sourceFor(file.getName(), file);
         } else if (src instanceof URL) {
             final URL url = (URL)src;
-            source = new Source(url.toString(), url);
+            source = sourceFor(url.toString(), url);
         } else if (src instanceof ScriptObject) {
             final ScriptObject sobj = (ScriptObject)src;
             if (sobj.has("script") && sobj.has("name")) {
                 final String script = JSType.toString(sobj.get("script"));
                 final String name   = JSType.toString(sobj.get("name"));
-                source = new Source(name, script);
+                source = sourceFor(name, script);
             }
         } else if (src instanceof Map) {
             final Map<?,?> map = (Map<?,?>)src;
             if (map.containsKey("script") && map.containsKey("name")) {
                 final String script = JSType.toString(map.get("script"));
                 final String name   = JSType.toString(map.get("name"));
-                source = new Source(name, script);
+                source = sourceFor(name, script);
             }
         }
 
@@ -861,6 +962,11 @@
         return ((ScriptObject)Context.getGlobal()).getContext();
     }
 
+    static Context getContextTrustedOrNull() {
+        final Global global = Context.getGlobal();
+        return global == null ? null : ((ScriptObject)global).getContext();
+    }
+
     /**
      * Try to infer Context instance from the Class. If we cannot,
      * then get it from the thread local variable.
@@ -932,17 +1038,32 @@
             return script;
         }
 
-        final FunctionNode functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
-        if (errors.hasErrors()) {
-            return null;
+        CompiledScript compiledScript = null;
+        FunctionNode functionNode = null;
+
+        if (!env._parse_only && codeStore != null) {
+            try {
+                compiledScript = codeStore.getScript(source);
+            } catch (IOException | ClassNotFoundException e) {
+                getLogger(Compiler.class).warning("Error loading ", source, " from cache: ", e);
+                // Fall back to normal compilation
+            }
         }
 
-        if (env._print_ast) {
-            getErr().println(new ASTWriter(functionNode));
-        }
+        if (compiledScript == null) {
+            functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
 
-        if (env._print_parse) {
-            getErr().println(new PrintVisitor(functionNode, true, false));
+            if (errors.hasErrors()) {
+                return null;
+            }
+
+            if (env._print_ast) {
+                getErr().println(new ASTWriter(functionNode));
+            }
+
+            if (env._print_parse) {
+                getErr().println(new PrintVisitor(functionNode, true, false));
+            }
         }
 
         if (env._parse_only) {
@@ -954,19 +1075,23 @@
         final CodeSource   cs     = new CodeSource(url, (CodeSigner[])null);
         final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
 
-        final CompilationPhases phases = Compiler.CompilationPhases.COMPILE_ALL;
+        if (functionNode != null) {
+            final CompilationPhases phases = Compiler.CompilationPhases.COMPILE_ALL;
 
-        final Compiler compiler = new Compiler(
-                this,
-                env,
-                installer,
-                source,
-                functionNode.getSourceURL(),
-                strict | functionNode.isStrict());
+            final Compiler compiler = new Compiler(
+                    this,
+                    env,
+                    installer,
+                    source,
+                    functionNode.getSourceURL(),
+                    strict | functionNode.isStrict());
 
-        script = compiler.compile(functionNode, phases).getRootClass();
+            script = compiler.compile(functionNode, phases).getRootClass();
+        } else {
+            script = install(compiledScript, installer);
+        }
+
         cacheClass(source, script);
-
         return script;
     }
 
@@ -988,6 +1113,45 @@
         return uniqueScriptId.getAndIncrement();
     }
 
+
+    /**
+     * Install a previously compiled class from the code cache.
+     *
+     * @param compiledScript cached script containing class bytes and constants
+     * @return main script class
+     */
+    private static Class<?> install(final CompiledScript compiledScript, final CodeInstaller<ScriptEnvironment> installer) {
+
+        final Map<String, Class<?>> installedClasses = new HashMap<>();
+        final Source   source        = compiledScript.getSource();
+        final Object[] constants     = compiledScript.getConstants();
+        final String   rootClassName = compiledScript.getMainClassName();
+        final byte[]   rootByteCode  = compiledScript.getClassBytes().get(rootClassName);
+        final Class<?> rootClass     = installer.install(rootClassName, rootByteCode);
+
+        installedClasses.put(rootClassName, rootClass);
+
+        for (final Map.Entry<String, byte[]> entry : compiledScript.getClassBytes().entrySet()) {
+            final String className = entry.getKey();
+            if (className.equals(rootClassName)) {
+                continue;
+            }
+            final byte[] code = entry.getValue();
+
+            installedClasses.put(className, installer.install(className, code));
+        }
+
+        installer.initialize(installedClasses.values(), source, constants);
+
+        for (Object constant : constants) {
+            if (constant instanceof RecompilableScriptFunctionData) {
+                ((RecompilableScriptFunctionData) constant).setCodeAndSource(installedClasses, source);
+            }
+        }
+
+        return rootClass;
+    }
+
     /**
      * Cache for compiled script classes.
      */
--- a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Wed May 28 16:53:43 2014 +0200
@@ -94,11 +94,6 @@
             // is too conservative a check. However, isConstructor(mh) always implies isConstructor param
             assert isConstructor();
             code.add(CompiledFunction.createBuiltInConstructor(mh));
-/*=======
-            final MethodHandle invoker = MH.insertArguments(mh, 0, false);
-            final MethodHandle constructor = composeConstructor(MH.insertArguments(mh, 0, true));
-            code.add(new CompiledFunction(mh.type(), invoker, constructor));
->>>>>>> theirs*/
         } else {
             code.add(new CompiledFunction(mh));
         }
--- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Wed May 28 16:53:43 2014 +0200
@@ -39,6 +39,8 @@
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
 /**
  * Utilities used by "JSON" object implementation.
  */
@@ -77,9 +79,7 @@
      */
     public static Object parse(final Object text, final Object reviver) {
         final String     str     = JSType.toString(text);
-        final JSONParser parser  = new JSONParser(
-                new Source("<json>", str),
-                new Context.ThrowErrorManager());
+        final JSONParser parser  = new JSONParser(sourceFor("<json>", str), new Context.ThrowErrorManager());
 
         Node node;
 
--- a/src/jdk/nashorn/internal/runtime/JSType.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/JSType.java	Wed May 28 16:53:43 2014 +0200
@@ -651,7 +651,9 @@
 
         // encode integer part from least significant digit, then reverse
         do {
-            sb.append(chars.charAt((int) (intPart % radix)));
+            final double remainder = intPart % radix;
+            sb.append(chars.charAt((int) remainder));
+            intPart -= remainder;
             intPart /= radix;
         } while (intPart >= 1.0);
 
--- a/src/jdk/nashorn/internal/runtime/Property.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/Property.java	Wed May 28 16:53:43 2014 +0200
@@ -29,10 +29,10 @@
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
 
+import java.io.Serializable;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.SwitchPoint;
 import java.util.Objects;
-
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 
 /**
@@ -44,7 +44,7 @@
  * @see AccessorProperty
  * @see UserAccessorProperty
  */
-public abstract class Property {
+public abstract class Property implements Serializable {
     /*
      * ECMA 8.6.1 Property Attributes
      *
@@ -100,6 +100,8 @@
     /** SwitchPoint that is invalidated when property is changed, optional */
     protected SwitchPoint changeCallback;
 
+    private static final long serialVersionUID = 2099814273074501176L;
+
     /**
      * Constructor
      *
@@ -394,6 +396,13 @@
     public abstract MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint);
 
     /**
+     * Hook to initialize method handles after deserialization.
+     *
+     * @param structure the structure class
+     */
+    abstract void initMethodHandles(final Class<?> structure);
+
+    /**
      * Get the key for this property. This key is an ordinary string. The "name".
      * @return key for property
      */
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java	Wed May 28 16:53:43 2014 +0200
@@ -29,6 +29,10 @@
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.lang.invoke.SwitchPoint;
 import java.lang.ref.SoftReference;
 import java.util.Arrays;
@@ -37,6 +41,7 @@
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.WeakHashMap;
+import jdk.nashorn.internal.scripts.JO;
 
 /**
  * Map of object properties. The PropertyMap is the "template" for JavaScript object
@@ -47,7 +52,7 @@
  * All property maps are immutable. If a property is added, modified or removed, the mutator
  * will return a new map.
  */
-public final class PropertyMap implements Iterable<Object> {
+public final class PropertyMap implements Iterable<Object>, Serializable {
     /** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
     public static final int NOT_EXTENSIBLE        = 0b0000_0001;
     /** Does this map contain valid array keys? */
@@ -57,7 +62,7 @@
     private int flags;
 
     /** Map of properties. */
-    private final PropertyHashMap properties;
+    private transient PropertyHashMap properties;
 
     /** Number of fields in use. */
     private int fieldCount;
@@ -68,17 +73,22 @@
     /** Length of spill in use. */
     private int spillLength;
 
+    /** Structure class name */
+    private String className;
+
     /** {@link SwitchPoint}s for gets on inherited properties. */
-    private HashMap<String, SwitchPoint> protoGetSwitches;
+    private transient HashMap<String, SwitchPoint> protoGetSwitches;
 
     /** History of maps, used to limit map duplication. */
-    private WeakHashMap<Property, SoftReference<PropertyMap>> history;
+    private transient WeakHashMap<Property, SoftReference<PropertyMap>> history;
 
     /** History of prototypes, used to limit map duplication. */
-    private WeakHashMap<PropertyMap, SoftReference<PropertyMap>> protoHistory;
+    private transient WeakHashMap<PropertyMap, SoftReference<PropertyMap>> protoHistory;
 
     /** property listeners */
-    private PropertyListeners listeners;
+    private transient PropertyListeners listeners;
+
+    private static final long serialVersionUID = -7041836752008732533L;
 
     /**
      * Constructor.
@@ -89,8 +99,10 @@
      * @param spillLength  Number of spill slots used.
      * @param containsArrayKeys True if properties contain numeric keys
      */
-    private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum, final int spillLength, final boolean containsArrayKeys) {
+    private PropertyMap(final PropertyHashMap properties, final String className, final int fieldCount,
+                        final int fieldMaximum, final int spillLength, final boolean containsArrayKeys) {
         this.properties   = properties;
+        this.className    = className;
         this.fieldCount   = fieldCount;
         this.fieldMaximum = fieldMaximum;
         this.spillLength  = spillLength;
@@ -145,7 +157,25 @@
         if (Context.DEBUG) {
             duplicatedCount++;
         }
-        return new PropertyMap(this.properties, 0, 0, 0, containsArrayKeys());
+        return new PropertyMap(this.properties, this.className, 0, 0, 0, containsArrayKeys());
+    }
+
+    private void writeObject(final ObjectOutputStream out) throws IOException {
+        out.defaultWriteObject();
+        out.writeObject(properties.getProperties());
+    }
+
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+
+        final Property[] props = (Property[]) in.readObject();
+        this.properties = EMPTY_HASHMAP.immutableAdd(props);
+
+        assert className != null;
+        final Class<?> structure = Context.forStructureClass(className);
+        for (Property prop : props) {
+            prop.initMethodHandles(structure);
+        }
     }
 
     /**
@@ -160,9 +190,9 @@
      * @param spillLength  Number of used spill slots.
      * @return New {@link PropertyMap}.
      */
-    public static PropertyMap newMap(final Collection<Property> properties, final int fieldCount, final int fieldMaximum,  final int spillLength) {
+    public static PropertyMap newMap(final Collection<Property> properties, final String className, final int fieldCount, final int fieldMaximum,  final int spillLength) {
         final PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
-        return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength, false);
+        return new PropertyMap(newProperties, className, fieldCount, fieldMaximum, spillLength, false);
     }
 
     /**
@@ -175,7 +205,7 @@
      * @return New {@link PropertyMap}.
      */
     public static PropertyMap newMap(final Collection<Property> properties) {
-        return properties == null || properties.isEmpty()? newMap() : newMap(properties, 0, 0, 0);
+        return properties == null || properties.isEmpty()? newMap() : newMap(properties, JO.class.getName(), 0, 0, 0);
     }
 
     /**
@@ -184,7 +214,7 @@
      * @return New empty {@link PropertyMap}.
      */
     public static PropertyMap newMap() {
-        return new PropertyMap(EMPTY_HASHMAP, 0, 0, 0, false);
+        return new PropertyMap(EMPTY_HASHMAP, JO.class.getName(), 0, 0, 0, false);
     }
 
     /**
--- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed May 28 16:53:43 2014 +0200
@@ -27,6 +27,8 @@
 
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 
+import java.io.IOException;
+import java.io.Serializable;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -34,7 +36,6 @@
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-
 import jdk.internal.dynalink.support.NameCodec;
 import jdk.nashorn.internal.codegen.CompileUnit;
 import jdk.nashorn.internal.codegen.Compiler;
@@ -54,6 +55,7 @@
 import jdk.nashorn.internal.runtime.logging.Loggable;
 import jdk.nashorn.internal.runtime.logging.Logger;
 import jdk.nashorn.internal.runtime.options.Options;
+import jdk.nashorn.internal.scripts.JS;
 
 /**
  * This is a subclass that represents a script function that may be regenerated,
@@ -79,10 +81,14 @@
     // Source object.
     private final String sourceURL;
 
+    /** The line number where this function begins. */
     private final int lineNumber;
 
     /** Source from which FunctionNode was parsed. */
-    private final Source source;
+    private transient Source source;
+
+    /** Allows us to retrieve the method handle for this function once the code is compiled */
+    private MethodLocator methodLocator;
 
     /** Token of this function within the source. */
     private final long token;
@@ -91,13 +97,13 @@
     private final PropertyMap allocatorMap;
 
     /** Code installer used for all further recompilation/specialization of this ScriptFunction */
-    private final CodeInstaller<ScriptEnvironment> installer;
+    private transient CodeInstaller<ScriptEnvironment> installer;
 
     /** Name of class where allocator function resides */
     private final String allocatorClassName;
 
     /** lazily generated allocator */
-    private MethodHandle allocator;
+    private transient MethodHandle allocator;
 
     private final Map<Integer, RecompilableScriptFunctionData> nestedFunctions;
 
@@ -110,20 +116,19 @@
 
     private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
 
-    private final DebugLogger log;
+    private transient DebugLogger log;
 
     private final Map<String, Integer> externalScopeDepths;
 
     private final Set<String> internalSymbols;
 
-    private final Context context;
+    private static final int GET_SET_PREFIX_LENGTH = "*et ".length();
 
-    private static final int GET_SET_PREFIX_LENGTH = "*et ".length();
+    private static final long serialVersionUID = 4914839316174633726L;
 
     /**
      * Constructor - public as scripts use it
      *
-     * @param context             context
      * @param functionNode        functionNode that represents this function code
      * @param installer           installer for code regeneration versions of this function
      * @param allocatorClassName  name of our allocator class, will be looked up dynamically if used as a constructor
@@ -134,7 +139,6 @@
      * @param internalSymbols     internal symbols to method, defined in its scope
      */
     public RecompilableScriptFunctionData(
-        final Context context,
         final FunctionNode functionNode,
         final CodeInstaller<ScriptEnvironment> installer,
         final String allocatorClassName,
@@ -148,7 +152,6 @@
               Math.min(functionNode.getParameters().size(), MAX_ARITY),
               getFlags(functionNode));
 
-        this.context             = context;
         this.functionName        = functionNode.getName();
         this.lineNumber          = functionNode.getLineNumber();
         this.isDeclared          = functionNode.isDeclared();
@@ -163,14 +166,14 @@
         this.allocatorMap        = allocatorMap;
         this.nestedFunctions     = nestedFunctions;
         this.externalScopeDepths = externalScopeDepths;
-        this.internalSymbols     = internalSymbols;
+        this.internalSymbols     = new HashSet<>(internalSymbols);
 
         for (final RecompilableScriptFunctionData nfn : nestedFunctions.values()) {
             assert nfn.getParent() == null;
             nfn.setParent(this);
         }
 
-        this.log = initLogger(context);
+        createLogger();
     }
 
     @Override
@@ -237,6 +240,13 @@
         return "function " + (name == null ? "" : name) + "() { [native code] }";
     }
 
+    public void setCodeAndSource(final Map<String, Class<?>> code, final Source source) {
+        this.source = source;
+        if (methodLocator != null) {
+            methodLocator.setClass(code.get(methodLocator.getClassName()));
+        }
+    }
+
     @Override
     public String toString() {
         return super.toString() + '@' + functionNodeId;
@@ -336,6 +346,7 @@
         final boolean isProgram = functionNodeId == FunctionNode.FIRST_FUNCTION_ID;
         // NOTE: If we aren't recompiling the top-level program, we decrease functionNodeId 'cause we'll have a synthetic program node
         final int descPosition = Token.descPosition(token);
+        final Context context = Context.getContextTrusted();
         final Parser parser = new Parser(
             context.getEnv(),
             source,
@@ -378,6 +389,7 @@
     }
 
     Compiler getCompiler(final FunctionNode functionNode, final MethodType actualCallSiteType, final ScriptObject runtimeScope, final Map<Integer, Type> ipp, final int[] cep) {
+        final Context context = Context.getContextTrusted();
         return new Compiler(
                 context,
                 context.getEnv(),
@@ -406,10 +418,6 @@
         return getCompiler(fn, actualCallSiteType, runtimeScope).compile(fn, CompilationPhases.COMPILE_ALL);
     }
 
-    Context getContext() {
-        return context;
-    }
-
     private MethodType explicitParams(final MethodType callSiteType) {
         if (CompiledFunction.isVarArgsType(callSiteType)) {
             return null;
@@ -481,6 +489,7 @@
             throw new IllegalStateException(functionNode.getName() + " id=" + functionNode.getId());
         }
         addCode(functionNode);
+        methodLocator = new MethodLocator(functionNode);
     }
 
     private CompiledFunction addCode(final MethodHandle target, final int fnFlags) {
@@ -542,7 +551,12 @@
         synchronized (code) {
             CompiledFunction existingBest = super.getBest(callSiteType, runtimeScope);
             if (existingBest == null) {
-                existingBest = addCode(compileTypeSpecialization(callSiteType, runtimeScope), callSiteType);
+                if(code.isEmpty() && methodLocator != null) {
+                    // This is a deserialized object, reconnect from method handle
+                    existingBest = addCode(methodLocator.getMethodHandle(), methodLocator.getFunctionFlags());
+                } else {
+                    existingBest = addCode(compileTypeSpecialization(callSiteType, runtimeScope), callSiteType);
+                }
             }
 
             assert existingBest != null;
@@ -653,4 +667,55 @@
 
         return true;
     }
+
+    /**
+     * Helper class that allows us to retrieve the method handle for this function once it has been generated.
+     */
+    private static class MethodLocator implements Serializable {
+        private transient Class<?> clazz;
+        private final String className;
+        private final String methodName;
+        private final MethodType methodType;
+        private final int functionFlags;
+
+        private static final long serialVersionUID = -5420835725902966692L;
+
+        MethodLocator(final FunctionNode functionNode) {
+            this.className  = functionNode.getCompileUnit().getUnitClassName();
+            this.methodName = functionNode.getName();
+            this.methodType = new FunctionSignature(functionNode).getMethodType();
+            this.functionFlags = functionNode.getFlags();
+
+            assert className != null;
+            assert methodName != null;
+        }
+
+        void setClass(final Class<?> clazz) {
+            if (!JS.class.isAssignableFrom(clazz)) {
+                throw new IllegalArgumentException();
+            }
+            this.clazz = clazz;
+        }
+
+        String getClassName() {
+            return className;
+        }
+
+        MethodHandle getMethodHandle() {
+            return MH.findStatic(LOOKUP, clazz, methodName, methodType);
+        }
+
+        int getFunctionFlags() {
+            return functionFlags;
+        }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        createLogger();
+    }
+
+    private void createLogger() {
+        log = initLogger(Context.getContextTrusted());
+    }
 }
--- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Wed May 28 16:53:43 2014 +0200
@@ -33,7 +33,6 @@
 import java.util.StringTokenizer;
 import java.util.TimeZone;
 import java.util.logging.Level;
-
 import jdk.nashorn.internal.codegen.Namespace;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.options.KeyValueOption;
@@ -65,6 +64,9 @@
     /** Only compile script, do not run it or generate other ScriptObjects */
     public final boolean _compile_only;
 
+    /** Accept "const" keyword and treat it as variable. Interim feature */
+    public final boolean _const_as_var;
+
     /** Accumulated callsite flags that will be used when bootstrapping script callsites */
     public final int     _callsite_flags;
 
@@ -132,6 +134,9 @@
      */
     public final FunctionStatementBehavior _function_statement;
 
+    /** Should lazy compilation take place */
+    public final boolean _lazy_compilation;
+
     /** Create a new class loaded for each compilation */
     public final boolean _loader_per_compile;
 
@@ -147,6 +152,9 @@
     /** Only parse the source code, do not compile */
     public final boolean _parse_only;
 
+    /** Enable disk cache for compiled scripts */
+    public final boolean _persistent_cache;
+
     /** Print the AST before lowering */
     public final boolean _print_ast;
 
@@ -219,6 +227,7 @@
 
         _class_cache_size     = options.getInteger("class.cache.size");
         _compile_only         = options.getBoolean("compile.only");
+        _const_as_var         = options.getBoolean("const.as.var");
         _debug_lines          = options.getBoolean("debug.lines");
         _dest_dir             = options.getString("d");
         _dump_on_error        = options.getBoolean("doe");
@@ -234,11 +243,13 @@
         }
         _fx                   = options.getBoolean("fx");
         _global_per_engine    = options.getBoolean("global.per.engine");
+        _lazy_compilation     = options.getBoolean("lazy.compilation");
         _loader_per_compile   = options.getBoolean("loader.per.compile");
         _no_java              = options.getBoolean("no.java");
         _no_syntax_extensions = options.getBoolean("no.syntax.extensions");
         _no_typed_arrays      = options.getBoolean("no.typed.arrays");
         _parse_only           = options.getBoolean("parse.only");
+        _persistent_cache     = options.getBoolean("persistent.code.cache");
         _print_ast            = options.getBoolean("print.ast");
         _print_lower_ast      = options.getBoolean("print.lower.ast");
         _print_code           = options.getString("print.code") != null;
--- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed May 28 16:53:43 2014 +0200
@@ -29,17 +29,21 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
 
+
 /**
  * A container for data needed to instantiate a specific {@link ScriptFunction} at runtime.
  * Instances of this class are created during codegen and stored in script classes'
  * constants array to reduce function instantiation overhead during runtime.
  */
-public abstract class ScriptFunctionData {
+public abstract class ScriptFunctionData implements Serializable {
     static final int MAX_ARITY = LinkerCallSite.ARGLIMIT;
     static {
         // Assert it fits in a byte, as that's what we store it in. It's just a size optimization though, so if needed
@@ -52,7 +56,7 @@
 
     /** All versions of this function that have been generated to code */
     // TODO: integrate it into ScriptFunctionData; there's not much reason for this to be in its own class.
-    protected final CompiledFunctions code;
+    protected transient CompiledFunctions code;
 
     /** Function flags */
     protected int flags;
@@ -93,6 +97,8 @@
     /** Flag for strict constructors */
     public static final int IS_STRICT_CONSTRUCTOR = IS_STRICT | IS_CONSTRUCTOR;
 
+    private static final long serialVersionUID = 4252901245508769114L;
+
     /**
      * Constructor
      *
@@ -793,4 +799,9 @@
         volatile MethodHandle invoker;
         volatile MethodHandle constructor;
     }
+
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        code = new CompiledFunctions(name);
+    }
 }
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed May 28 16:53:43 2014 +0200
@@ -99,7 +99,7 @@
  */
 
 public abstract class ScriptObject implements PropertyAccess {
-    /** __proto__ special property name */
+    /** __proto__ special property name inside object literals. ES6 draft. */
     public static final String PROTO_PROPERTY_NAME   = "__proto__";
 
     /** Search fall back routine name for "no such method" */
@@ -153,8 +153,11 @@
     /** Indexed array data. */
     private ArrayData arrayData;
 
-    static final MethodHandle GETPROTO           = findOwnMH_V("getProto", ScriptObject.class);
-    static final MethodHandle SETPROTOCHECK      = findOwnMH_V("setProtoCheck", void.class, Object.class);
+    /** Method handle to retrieve prototype of this object */
+    public static final MethodHandle GETPROTO      = findOwnMH_V("getProto", ScriptObject.class);
+    /** Method handle to set prototype of this object */
+    public static final MethodHandle SETPROTOCHECK = findOwnMH_V("setProtoCheck", void.class, Object.class);
+
     static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
     static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
 
@@ -680,22 +683,16 @@
     }
 
     /**
-     * Spec. mentions use of [[DefineOwnProperty]] for indexed properties in
-     * certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set
-     * method in such cases. This is because set method uses inherited setters (if any)
-     * from any object in proto chain such as Array.prototype, Object.prototype.
-     * This method directly sets a particular element value in the current object.
+     * Almost like defineOwnProperty(int,Object) for arrays this one does
+     * not add 'gap' elements (like the array one does).
      *
      * @param index key for property
      * @param value value to define
      */
-    public final void defineOwnProperty(final int index, final Object value) {
+    public void defineOwnProperty(final int index, final Object value) {
         assert isValidArrayIndex(index) : "invalid array index";
         final long longIndex = ArrayIndex.toLongIndex(index);
-        if (longIndex >= getArray().length()) {
-            // make array big enough to hold..
-            setArray(getArray().ensure(longIndex));
-        }
+        doesNotHaveEnsureDelete(longIndex, getArray().length(), false);
         setArray(getArray().set(index, value, false));
     }
 
@@ -1915,17 +1912,6 @@
         MethodHandle mh;
 
         if (find == null) {
-            if (PROTO_PROPERTY_NAME.equals(name)) {
-                return new GuardedInvocation(
-                        GETPROTO,
-                        explicitInstanceOfCheck ?
-                                getScriptObjectGuard(desc.getMethodType(), explicitInstanceOfCheck) :
-                                null,
-                        (SwitchPoint)null,
-                        explicitInstanceOfCheck ?
-                                null : ClassCastException.class);
-            }
-
             switch (operator) {
             case "getProp":
                 return noSuchProperty(desc, request);
@@ -2116,13 +2102,7 @@
                 return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
             }
         } else {
-            if (PROTO_PROPERTY_NAME.equals(name)) {
-                return new GuardedInvocation(
-                        SETPROTOCHECK,
-                        getScriptObjectGuard(desc.getMethodType(), explicitInstanceOfCheck),
-                        (SwitchPoint)null,
-                        explicitInstanceOfCheck ? null : ClassCastException.class);
-            } else if (!isExtensible()) {
+            if (!isExtensible()) {
                 return createEmptySetMethod(desc, explicitInstanceOfCheck, "object.non.extensible", false);
             }
         }
--- a/src/jdk/nashorn/internal/runtime/Source.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/Source.java	Wed May 28 16:53:43 2014 +0200
@@ -27,27 +27,40 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOError;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
+import java.lang.ref.WeakReference;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.net.URLConnection;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.Objects;
+import java.util.WeakHashMap;
+import jdk.nashorn.api.scripting.URLReader;
 import jdk.nashorn.internal.parser.Token;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
+import jdk.nashorn.internal.runtime.logging.Loggable;
+import jdk.nashorn.internal.runtime.logging.Logger;
 
 /**
  * Source objects track the origin of JavaScript entities.
- *
  */
-public final class Source {
+@Logger(name="source")
+public final class Source implements Loggable {
+    private static final int BUF_SIZE = 8 * 1024;
+    private static final Cache CACHE = new Cache();
+
     /**
      * Descriptive name of the source as supplied by the user. Used for error
      * reporting to the user. For example, SyntaxError will use this to print message.
@@ -62,49 +75,309 @@
      */
     private final String base;
 
-    /** Cached source content. */
-    private final char[] content;
-
-    /** Length of source content. */
-    private final int length;
+    /** Source content */
+    private final Data data;
 
     /** Cached hash code */
     private int hash;
 
-    /** Source URL if available */
-    private final URL url;
+    /** Message digest */
+    private byte[] digest;
 
-    private static final int BUFSIZE = 8 * 1024;
+    // Do *not* make this public, ever! Trusts the URL and content.
+    private Source(final String name, final String base, final Data data) {
+        this.name = name;
+        this.base = base;
+        this.data = data;
+    }
 
-    // Do *not* make this public ever! Trusts the URL and content. So has to be called
-    // from other public constructors. Note that this can not be some init method as
-    // we initialize final fields from here.
-    private Source(final String name, final String base, final char[] content, final URL url) {
-        this.name    = name;
-        this.base    = base;
-        this.content = content;
-        this.length  = content.length;
-        this.url     = url;
+    private static synchronized Source sourceFor(final String name, final String base, final URLData data) throws IOException {
+        try {
+            final Source newSource = new Source(name, base, data);
+            final Source existingSource = CACHE.get(newSource);
+            if (existingSource != null) {
+                // Force any access errors
+                data.checkPermissionAndClose();
+                return existingSource;
+            } else {
+                // All sources in cache must be fully loaded
+                data.load();
+                CACHE.put(newSource, newSource);
+                return newSource;
+            }
+        } catch (RuntimeException e) {
+            final Throwable cause = e.getCause();
+            if (cause instanceof IOException) {
+                throw (IOException) cause;
+            }
+            throw e;
+        }
+    }
+
+    private static class Cache extends WeakHashMap<Source, WeakReference<Source>> {
+        public Source get(final Source key) {
+            final WeakReference<Source> ref = super.get(key);
+            return ref == null ? null : ref.get();
+        }
+
+        public void put(final Source key, final Source value) {
+            assert !(value.data instanceof RawData);
+            put(key, new WeakReference<>(value));
+        }
+    }
+
+    // Wrapper to manage lazy loading
+    private static interface Data {
+
+        URL url();
+
+        int length();
+
+        long lastModified();
+
+        char[] array();
+    }
+
+    private static class RawData implements Data {
+        private final char[] array;
+        private int hash;
+
+        private RawData(final char[] array) {
+            this.array = Objects.requireNonNull(array);
+        }
+
+        private RawData(final String source) {
+            this.array = Objects.requireNonNull(source).toCharArray();
+        }
+
+        private RawData(final Reader reader) throws IOException {
+            this(readFully(reader));
+        }
+
+        @Override
+        public int hashCode() {
+            int h = hash;
+            if (h == 0) {
+                h = hash = Arrays.hashCode(array);
+            }
+            return h;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof RawData) {
+                return Arrays.equals(array, ((RawData)obj).array);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return new String(array());
+        }
+
+        @Override
+        public URL url() {
+            return null;
+        }
+
+        @Override
+        public int length() {
+            return array.length;
+        }
+
+        @Override
+        public long lastModified() {
+            return 0;
+        }
+
+        @Override
+        public char[] array() {
+            return array;
+        }
+
+
+    }
+
+    private static class URLData implements Data {
+        private final URL url;
+        protected final Charset cs;
+        private int hash;
+        protected char[] array;
+        protected int length;
+        protected long lastModified;
+
+        private URLData(final URL url, final Charset cs) {
+            this.url = Objects.requireNonNull(url);
+            this.cs = cs;
+        }
+
+        @Override
+        public int hashCode() {
+            int h = hash;
+            if (h == 0) {
+                h = hash = url.hashCode();
+            }
+            return h;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+            if (!(other instanceof URLData)) {
+                return false;
+            }
+
+            URLData otherData = (URLData) other;
+
+            if (url.equals(otherData.url)) {
+                // Make sure both have meta data loaded
+                try {
+                    if (isDeferred()) {
+                        // Data in cache is always loaded, and we only compare to cached data.
+                        assert !otherData.isDeferred();
+                        loadMeta();
+                    } else if (otherData.isDeferred()) {
+                        otherData.loadMeta();
+                    }
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+
+                // Compare meta data
+                return this.length == otherData.length && this.lastModified == otherData.lastModified;
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return new String(array());
+        }
+
+        @Override
+        public URL url() {
+            return url;
+        }
+
+        @Override
+        public int length() {
+            return length;
+        }
+
+        @Override
+        public long lastModified() {
+            return lastModified;
+        }
+
+        @Override
+        public char[] array() {
+            assert !isDeferred();
+            return array;
+        }
+
+        boolean isDeferred() {
+            return array == null;
+        }
+
+        protected void checkPermissionAndClose() throws IOException {
+            try (InputStream in = url.openStream()) {}
+            debug("permission checked for ", url);
+        }
+
+        protected void load() throws IOException {
+            if (array == null) {
+                final URLConnection c = url.openConnection();
+                try (InputStream in = c.getInputStream()) {
+                    array = cs == null ? readFully(in) : readFully(in, cs);
+                    length = array.length;
+                    lastModified = c.getLastModified();
+                    debug("loaded content for ", url);
+                }
+            }
+        }
+
+        protected void loadMeta() throws IOException {
+            if (length == 0 && lastModified == 0) {
+                final URLConnection c = url.openConnection();
+                length = c.getContentLength();
+                lastModified = c.getLastModified();
+                debug("loaded metadata for ", url);
+            }
+        }
+    }
+
+    private static class FileData extends URLData {
+        private final File file;
+
+        private FileData(final File file, final Charset cs) {
+            super(getURLFromFile(file), cs);
+            this.file = file;
+
+        }
+
+        @Override
+        protected void checkPermissionAndClose() throws IOException {
+            if (!file.canRead()) {
+                throw new FileNotFoundException(file + " (Permission Denied)");
+            }
+            debug("permission checked for ", file);
+        }
+
+        @Override
+        protected void loadMeta() {
+            if (length == 0 && lastModified == 0) {
+                length = (int) file.length();
+                lastModified = file.lastModified();
+                debug("loaded metadata for ", file);
+            }
+        }
+
+        @Override
+        protected void load() throws IOException {
+            if (array == null) {
+                array = cs == null ? readFully(file) : readFully(file, cs);
+                length = array.length;
+                lastModified = file.lastModified();
+                debug("loaded content for ", file);
+            }
+        }
+    }
+
+    private static void debug(final Object... msg) {
+        final DebugLogger logger = getLoggerStatic();
+        if (logger != null) {
+            logger.info(msg);
+        }
+    }
+
+    private char[] data() {
+        return data.array();
     }
 
     /**
-     * Constructor
+     * Returns an instance
      *
      * @param name    source name
      * @param content contents as char array
      */
-    public Source(final String name, final char[] content) {
-        this(name, baseName(name, null), content, null);
+    public static Source sourceFor(final String name, final char[] content) {
+        return new Source(name, baseName(name), new RawData(content));
     }
 
     /**
-     * Constructor
+     * Returns an instance
      *
      * @param name    source name
      * @param content contents as string
      */
-    public Source(final String name, final String content) {
-        this(name, content.toCharArray());
+    public static Source sourceFor(final String name, final String content) {
+        return new Source(name, baseName(name), new RawData(content));
     }
 
     /**
@@ -115,8 +388,8 @@
      *
      * @throws IOException if source cannot be loaded
      */
-    public Source(final String name, final URL url) throws IOException {
-        this(name, baseURL(url, null), readFully(url), url);
+    public static Source sourceFor(final String name, final URL url) throws IOException {
+        return sourceFor(name, url, null);
     }
 
     /**
@@ -128,8 +401,8 @@
      *
      * @throws IOException if source cannot be loaded
      */
-    public Source(final String name, final URL url, final Charset cs) throws IOException {
-        this(name, baseURL(url, null), readFully(url, cs), url);
+    public static Source sourceFor(final String name, final URL url, final Charset cs) throws IOException {
+        return sourceFor(name, baseURL(url), new URLData(url, cs));
     }
 
     /**
@@ -140,8 +413,8 @@
      *
      * @throws IOException if source cannot be loaded
      */
-    public Source(final String name, final File file) throws IOException {
-        this(name, dirName(file, null), readFully(file), getURLFromFile(file));
+    public static Source sourceFor(final String name, final File file) throws IOException {
+        return sourceFor(name, file, null);
     }
 
     /**
@@ -153,8 +426,25 @@
      *
      * @throws IOException if source cannot be loaded
      */
-    public Source(final String name, final File file, final Charset cs) throws IOException {
-        this(name, dirName(file, null), readFully(file, cs), getURLFromFile(file));
+    public static Source sourceFor(final String name, final File file, final Charset cs) throws IOException {
+        final File absFile = file.getAbsoluteFile();
+        return sourceFor(name, dirName(absFile, null), new FileData(file, cs));
+    }
+
+    /**
+     * Returns an instance
+     *
+     * @param name source name
+     * @param reader reader from which source can be loaded
+     * @throws IOException if source cannot be loaded
+     */
+    public static Source sourceFor(final String name, final Reader reader) throws IOException {
+        // Extract URL from URLReader to defer loading and reuse cached data if available.
+        if (reader instanceof URLReader) {
+            final URLReader urlReader = (URLReader) reader;
+            return sourceFor(name, urlReader.getURL(), urlReader.getCharset());
+        }
+        return new Source(name, baseName(name), new RawData(reader));
     }
 
     @Override
@@ -162,21 +452,18 @@
         if (this == obj) {
             return true;
         }
-
         if (!(obj instanceof Source)) {
             return false;
         }
-
-        final Source src = (Source)obj;
-        // Only compare content as a last resort measure
-        return length == src.length && Objects.equals(url, src.url) && Objects.equals(name, src.name) && Arrays.equals(content, src.content);
+        final Source other = (Source) obj;
+        return Objects.equals(name, other.name) && data.equals(other.data);
     }
 
     @Override
     public int hashCode() {
         int h = hash;
         if (h == 0) {
-            h = hash = Arrays.hashCode(content) ^ Objects.hashCode(name);
+            h = hash = data.hashCode() ^ Objects.hashCode(name);
         }
         return h;
     }
@@ -186,7 +473,7 @@
      * @return Source content.
      */
     public String getString() {
-        return new String(content, 0, length);
+        return data.toString();
     }
 
     /**
@@ -198,6 +485,14 @@
     }
 
     /**
+     * Get the last modified time of this script.
+     * @return Last modified time.
+     */
+    public long getLastModified() {
+        return data.lastModified();
+    }
+
+    /**
      * Get the "directory" part of the file or "base" of the URL.
      * @return base of file or URL.
      */
@@ -212,7 +507,7 @@
      * @return Source content portion.
      */
     public String getString(final int start, final int len) {
-        return new String(content, start, len);
+        return new String(data(), start, len);
     }
 
     /**
@@ -223,7 +518,7 @@
     public String getString(final long token) {
         final int start = Token.descPosition(token);
         final int len = Token.descLength(token);
-        return new String(content, start, len);
+        return new String(data(), start, len);
     }
 
     /**
@@ -233,7 +528,7 @@
      * @return URL source or null
      */
     public URL getURL() {
-        return url;
+        return data.url();
     }
 
     /**
@@ -242,8 +537,9 @@
      * @return Index of first character of line.
      */
     private int findBOLN(final int position) {
+        final char[] data = data();
         for (int i = position - 1; i > 0; i--) {
-            final char ch = content[i];
+            final char ch = data[i];
 
             if (ch == '\n' || ch == '\r') {
                 return i + 1;
@@ -259,8 +555,10 @@
      * @return Index of last character of line.
      */
     private int findEOLN(final int position) {
-         for (int i = position; i < length; i++) {
-            final char ch = content[i];
+        final char[] data = data();
+        final int length = data.length;
+        for (int i = position; i < length; i++) {
+            final char ch = data[i];
 
             if (ch == '\n' || ch == '\r') {
                 return i - 1;
@@ -280,11 +578,12 @@
      * @return Line number.
      */
     public int getLine(final int position) {
+        final char[] data = data();
         // Line count starts at 1.
         int line = 1;
 
         for (int i = 0; i < position; i++) {
-            final char ch = content[i];
+            final char ch = data[i];
             // Works for both \n and \r\n.
             if (ch == '\n') {
                 line++;
@@ -315,7 +614,7 @@
         // Find end of this line.
         final int last = findEOLN(position);
 
-        return new String(content, first, last - first + 1);
+        return new String(data(), first, last - first + 1);
     }
 
     /**
@@ -323,7 +622,7 @@
      * @return content
      */
     public char[] getContent() {
-        return content.clone();
+        return data().clone();
     }
 
     /**
@@ -331,19 +630,18 @@
      * @return length
      */
     public int getLength() {
-        return length;
+        return data.length();
     }
 
     /**
      * Read all of the source until end of file. Return it as char array
      *
-     * @param reader  reader opened to source stream
+     * @param reader reader opened to source stream
      * @return source as content
-     *
      * @throws IOException if source could not be read
      */
     public static char[] readFully(final Reader reader) throws IOException {
-        final char[]        arr = new char[BUFSIZE];
+        final char[]        arr = new char[BUF_SIZE];
         final StringBuilder sb  = new StringBuilder();
 
         try {
@@ -361,9 +659,8 @@
     /**
      * Read all of the source until end of file. Return it as char array
      *
-     * @param file  source file
+     * @param file source file
      * @return source as content
-     *
      * @throws IOException if source could not be read
      */
     public static char[] readFully(final File file) throws IOException {
@@ -376,10 +673,9 @@
     /**
      * Read all of the source until end of file. Return it as char array
      *
-     * @param file  source file
+     * @param file source file
      * @param cs Charset used to convert bytes to chars
      * @return source as content
-     *
      * @throws IOException if source could not be read
      */
     public static char[] readFully(final File file, final Charset cs) throws IOException {
@@ -388,7 +684,7 @@
         }
 
         final byte[] buf = Files.readAllBytes(file.toPath());
-        return (cs != null)? new String(buf, cs).toCharArray() : byteToCharArray(buf);
+        return (cs != null) ? new String(buf, cs).toCharArray() : byteToCharArray(buf);
     }
 
     /**
@@ -396,7 +692,6 @@
      *
      * @param url URL to read content from
      * @return source as content
-     *
      * @throws IOException if source could not be read
      */
     public static char[] readFully(final URL url) throws IOException {
@@ -409,7 +704,6 @@
      * @param url URL to read content from
      * @param cs Charset used to convert bytes to chars
      * @return source as content
-     *
      * @throws IOException if source could not be read
      */
     public static char[] readFully(final URL url, final Charset cs) throws IOException {
@@ -417,55 +711,85 @@
     }
 
     /**
+     * Get a message digest for this source.
+     *
+     * @return a message digest for this source
+     */
+    public synchronized byte[] getDigest() {
+        if (digest == null) {
+            final char[] content = data();
+            final byte[] bytes = new byte[content.length * 2];
+
+            for (int i = 0; i < content.length; i++) {
+                bytes[i * 2]     = (byte)  (content[i] & 0x00ff);
+                bytes[i * 2 + 1] = (byte) ((content[i] & 0xff00) >> 8);
+            }
+
+            try {
+                final MessageDigest md = MessageDigest.getInstance("SHA-1");
+                if (name != null) {
+                    md.update(name.getBytes(StandardCharsets.UTF_8));
+                }
+                if (base != null) {
+                    md.update(base.getBytes(StandardCharsets.UTF_8));
+                }
+                if (getURL() != null) {
+                    md.update(getURL().toString().getBytes(StandardCharsets.UTF_8));
+                }
+                digest = md.digest(bytes);
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return digest;
+    }
+
+    /**
      * Get the base url. This is currently used for testing only
      * @param url a URL
      * @return base URL for url
      */
     public static String baseURL(final URL url) {
-        return baseURL(url, null);
-    }
-
-    private static String baseURL(final URL url, final String defaultValue) {
         if (url.getProtocol().equals("file")) {
             try {
                 final Path path = Paths.get(url.toURI());
                 final Path parent = path.getParent();
-                return (parent != null) ? (parent + File.separator) : defaultValue;
+                return (parent != null) ? (parent + File.separator) : null;
             } catch (final SecurityException | URISyntaxException | IOError e) {
-                return defaultValue;
+                return null;
             }
         }
 
         // FIXME: is there a better way to find 'base' URL of a given URL?
         String path = url.getPath();
         if (path.isEmpty()) {
-            return defaultValue;
+            return null;
         }
         path = path.substring(0, path.lastIndexOf('/') + 1);
         final int port = url.getPort();
         try {
             return new URL(url.getProtocol(), url.getHost(), port, path).toString();
         } catch (final MalformedURLException e) {
-            return defaultValue;
+            return null;
         }
     }
 
-    private static String dirName(final File file, final String defaultValue) {
+    private static String dirName(final File file, final String DEFAULT_BASE_NAME) {
         final String res = file.getParent();
-        return (res != null)? (res + File.separator) : defaultValue;
+        return (res != null) ? (res + File.separator) : DEFAULT_BASE_NAME;
     }
 
     // fake directory like name
-    private static String baseName(final String name, final String defaultValue) {
+    private static String baseName(final String name) {
         int idx = name.lastIndexOf('/');
         if (idx == -1) {
             idx = name.lastIndexOf('\\');
         }
-        return (idx != -1)? name.substring(0, idx + 1) : defaultValue;
+        return (idx != -1) ? name.substring(0, idx + 1) : null;
     }
 
     private static char[] readFully(final InputStream is, final Charset cs) throws IOException {
-        return (cs != null)? new String(readBytes(is), cs).toCharArray() : readFully(is);
+        return (cs != null) ? new String(readBytes(is), cs).toCharArray() : readFully(is);
     }
 
     private static char[] readFully(final InputStream is) throws IOException {
@@ -476,19 +800,19 @@
         Charset cs = StandardCharsets.UTF_8;
         int start = 0;
         // BOM detection.
-        if (bytes.length > 1 && bytes[0] == (byte)0xFE && bytes[1] == (byte)0xFF) {
+        if (bytes.length > 1 && bytes[0] == (byte) 0xFE && bytes[1] == (byte) 0xFF) {
             start = 2;
             cs = StandardCharsets.UTF_16BE;
-        } else if (bytes.length > 1 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE) {
+        } else if (bytes.length > 1 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE) {
             start = 2;
             cs = StandardCharsets.UTF_16LE;
-        } else if (bytes.length > 2 && bytes[0] == (byte)0xEF && bytes[1] == (byte)0xBB && bytes[2] == (byte)0xBF) {
+        } else if (bytes.length > 2 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) {
             start = 3;
             cs = StandardCharsets.UTF_8;
-        } else if (bytes.length > 3 && bytes[0] == (byte)0xFF && bytes[1] == (byte)0xFE && bytes[2] == 0 && bytes[3] == 0) {
+        } else if (bytes.length > 3 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE && bytes[2] == 0 && bytes[3] == 0) {
             start = 4;
             cs = Charset.forName("UTF-32LE");
-        } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte)0xFE && bytes[3] == (byte)0xFF) {
+        } else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF) {
             start = 4;
             cs = Charset.forName("UTF-32BE");
         }
@@ -497,7 +821,7 @@
     }
 
     static byte[] readBytes(final InputStream is) throws IOException {
-        final byte[] arr = new byte[BUFSIZE];
+        final byte[] arr = new byte[BUF_SIZE];
         try {
             try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
                 int numBytes;
@@ -523,4 +847,19 @@
             return null;
         }
     }
+
+    private static DebugLogger getLoggerStatic() {
+        final Context context = Context.getContextTrustedOrNull();
+        return context == null ? null : context.getLogger(Source.class);
+    }
+
+    @Override
+    public DebugLogger initLogger(Context context) {
+        return context.getLogger(this.getClass());
+    }
+
+    @Override
+    public DebugLogger getLogger() {
+        return initLogger(Context.getContextTrusted());
+    }
 }
--- a/src/jdk/nashorn/internal/runtime/SpillProperty.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/SpillProperty.java	Wed May 28 16:53:43 2014 +0200
@@ -25,16 +25,18 @@
 
 package jdk.nashorn.internal.runtime;
 
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 
-import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
-import static jdk.nashorn.internal.lookup.Lookup.MH;
-
 /**
  * Spill property
  */
 public class SpillProperty extends AccessorProperty {
+    private static final long serialVersionUID = 3028496245198669460L;
+
     private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
 
     private static final MethodHandle PARRAY_GETTER = MH.asType(MH.getter(LOOKUP, ScriptObject.class, "primitiveSpill",  long[].class), MH.type(long[].class, Object.class));
--- a/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Wed May 28 16:53:43 2014 +0200
@@ -56,6 +56,8 @@
  */
 public final class UserAccessorProperty extends SpillProperty {
 
+    private static final long serialVersionUID = -5928687246526840321L;
+
     static class Accessors {
         Object getter;
         Object setter;
@@ -257,6 +259,11 @@
     }
 
     @Override
+    void initMethodHandles(final Class<?> structure) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public ScriptFunction getGetterFunction(final ScriptObject sobj) {
         final Object value = getAccessors(sobj).getter;
         return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java	Wed May 28 16:53:43 2014 +0200
@@ -141,6 +141,21 @@
         return this;
     }
 
+    private static void printTrace(final Throwable t, String msg) {
+        final java.io.StringWriter sw = new java.io.StringWriter();
+        final java.io.PrintWriter pw = new java.io.PrintWriter(sw, false);
+        pw.println(msg);
+        final StackTraceElement[] trace = t.getStackTrace();
+        for(final StackTraceElement e: trace) {
+            pw.println(" at " + e);
+            if(e.getClassName().startsWith("jdk.nashorn.")) {
+                break;
+            }
+        }
+        pw.flush();
+        System.out.println(sw.toString());
+    }
+
     @Override
     public Type getOptimisticType() {
         return underlying.getOptimisticType();
--- a/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java	Wed May 28 16:53:43 2014 +0200
@@ -36,17 +36,25 @@
     private long lo, hi;
 
     DeletedRangeArrayFilter(final ArrayData underlying, final long lo, final long hi) {
-        super(underlying);
+        super(maybeSparse(underlying, hi));
         this.lo = lo;
         this.hi = hi;
     }
 
+    private static ArrayData maybeSparse(final ArrayData underlying, final long hi) {
+        if(hi < SparseArrayData.MAX_DENSE_LENGTH || underlying instanceof SparseArrayData) {
+            return underlying;
+        }
+        return new SparseArrayData(underlying, underlying.length());
+    }
+
     private boolean isEmpty() {
         return lo > hi;
     }
 
     private boolean isDeleted(final int index) {
-        return lo <= index && index <= hi;
+        final long longIndex = ArrayIndex.toLongIndex(index);
+        return lo <= longIndex && longIndex <= hi;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java	Wed May 28 16:53:43 2014 +0200
@@ -162,8 +162,9 @@
             underlying = underlying.set(index, value, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
-            sparseMap.put(indexToKey(index), value);
-            setLength(Math.max(index + 1, length()));
+            final Long longIndex = indexToKey(index);
+            sparseMap.put(longIndex, value);
+            setLength(Math.max(longIndex + 1, length()));
         }
 
         return this;
@@ -176,8 +177,9 @@
             underlying = underlying.set(index, value, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
-            sparseMap.put(indexToKey(index), value);
-            setLength(Math.max(index + 1, length()));
+            final Long longIndex = indexToKey(index);
+            sparseMap.put(longIndex, value);
+            setLength(Math.max(longIndex + 1, length()));
         }
         return this;
     }
@@ -189,8 +191,9 @@
             underlying = underlying.set(index, value, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
-            sparseMap.put(indexToKey(index), value);
-            setLength(Math.max(index + 1, length()));
+            final Long longIndex = indexToKey(index);
+            sparseMap.put(longIndex, value);
+            setLength(Math.max(longIndex + 1, length()));
         }
         return this;
     }
@@ -202,8 +205,9 @@
             underlying = underlying.set(index, value, strict);
             setLength(Math.max(underlying.length(), length()));
         } else {
-            sparseMap.put(indexToKey(index), value);
-            setLength(Math.max(index + 1, length()));
+            final Long longIndex = indexToKey(index);
+            sparseMap.put(longIndex, value);
+            setLength(Math.max(longIndex + 1, length()));
         }
         return this;
     }
@@ -321,7 +325,7 @@
     }
 
     private static Long indexToKey(final int index) {
-        return Long.valueOf(index & JSType.MAX_UINT);
+        return Long.valueOf(ArrayIndex.toLongIndex(index));
     }
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Wed May 28 16:53:43 2014 +0200
@@ -66,7 +66,6 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
-import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -135,24 +134,19 @@
  * implemented securely.
  */
 final class JavaAdapterBytecodeGenerator {
-    private static final Type CONTEXT_TYPE       = Type.getType(Context.class);
-    private static final Type OBJECT_TYPE        = Type.getType(Object.class);
-    private static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
-    private static final Type GLOBAL_TYPE        = Type.getType(Global.class);
-    private static final Type CLASS_TYPE         = Type.getType(Class.class);
+    private static final Type OBJECT_TYPE = Type.getType(Object.class);
+    private static final Type CLASS_TYPE  = Type.getType(Class.class);
 
-    static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
     static final String OBJECT_TYPE_NAME  = OBJECT_TYPE.getInternalName();
 
     static final String INIT = "<init>";
 
     static final String GLOBAL_FIELD_NAME = "global";
 
-    static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
-    static final String GLOBAL_TYPE_DESCRIPTOR = GLOBAL_TYPE.getDescriptor();
+    // "global" is declared as Object instead of Global - avoid static references to internal Nashorn classes when possible.
+    static final String GLOBAL_TYPE_DESCRIPTOR = OBJECT_TYPE.getDescriptor();
 
-
-    static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, GLOBAL_TYPE);
+    static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE);
     static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
 
     private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
@@ -163,7 +157,7 @@
             OBJECT_TYPE, STRING_TYPE, METHOD_TYPE_TYPE);
     private static final String GET_HANDLE_FUNCTION_DESCRIPTOR = Type.getMethodDescriptor(METHOD_HANDLE_TYPE,
             SCRIPT_FUNCTION_TYPE, METHOD_TYPE_TYPE);
-    private static final String GET_CLASS_INITIALIZER_DESCRIPTOR = Type.getMethodDescriptor(SCRIPT_OBJECT_TYPE);
+    private static final String GET_CLASS_INITIALIZER_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE);
     private static final Type RUNTIME_EXCEPTION_TYPE = Type.getType(RuntimeException.class);
     private static final Type THROWABLE_TYPE = Type.getType(Throwable.class);
     private static final Type UNSUPPORTED_OPERATION_TYPE = Type.getType(UnsupportedOperationException.class);
@@ -175,7 +169,7 @@
     private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName();
 
     private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
-    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(GLOBAL_TYPE);
+    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE);
     private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(CLASS_TYPE);
     private static final String EXPORT_RETURN_VALUE_METHOD_DESCRIPTOR = Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE);
     private static final String GET_CONVERTER_METHOD_DESCRIPTOR = Type.getMethodDescriptor(METHOD_HANDLE_TYPE, CLASS_TYPE);
@@ -603,11 +597,11 @@
     }
 
     private static void invokeGetGlobal(final InstructionAdapter mv) {
-        mv.invokestatic(CONTEXT_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR, false);
+        mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getGlobal", GET_GLOBAL_METHOD_DESCRIPTOR, false);
     }
 
     private static void invokeSetGlobal(final InstructionAdapter mv) {
-        mv.invokestatic(CONTEXT_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, false);
+        mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "setGlobal", SET_GLOBAL_METHOD_DESCRIPTOR, false);
     }
 
     /**
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Wed May 28 16:53:43 2014 +0200
@@ -30,9 +30,15 @@
 import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.nashorn.internal.codegen.DumpBytecode;
 import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptFunction;
 
 /**
  * This class encapsulates the bytecode of the adapter class and can be used to load it into the JVM as an actual Class.
@@ -44,6 +50,8 @@
 final class JavaAdapterClassLoader {
     private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
     private static final AccessControlContext GET_CONTEXT_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_GET_CONTEXT);
+    private static final Collection<String> VISIBLE_INTERNAL_CLASS_NAMES = Collections.unmodifiableCollection(new HashSet<>(
+            Arrays.asList(JavaAdapterServices.class.getName(), ScriptFunction.class.getName(), JSType.class.getName())));
 
     private final String className;
     private final byte[] classBytes;
@@ -87,13 +95,14 @@
             @Override
             public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
                 try {
+                    Context.checkPackageAccess(name);
                     return super.loadClass(name, resolve);
                 } catch (final SecurityException se) {
                     // we may be implementing an interface or extending a class that was
                     // loaded by a loader that prevents package.access. If so, it'd throw
                     // SecurityException for nashorn's classes!. For adapter's to work, we
-                    // should be able to refer to nashorn classes.
-                    if (name.startsWith("jdk.nashorn.internal.")) {
+                    // should be able to refer to the few classes it needs in its implementation.
+                    if(VISIBLE_INTERNAL_CLASS_NAMES.contains(name)) {
                         return myLoader.loadClass(name);
                     }
                     throw se;
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Wed May 28 16:53:43 2014 +0200
@@ -247,7 +247,7 @@
     }
 
     private static class AdapterInfo {
-        private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptObject.class, true);
+        private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptFunction.class, true);
 
         private final ClassLoader commonLoader;
         // TODO: soft reference the JavaAdapterClassLoader objects. They can be recreated when needed.
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java	Wed May 28 16:53:43 2014 +0200
@@ -116,8 +116,8 @@
      * static initializers.
      * @return the thread-local JS object used to define methods for the class being initialized.
      */
-    public static ScriptObject getClassOverrides() {
-        final ScriptObject overrides = classOverrides.get();
+    public static Object getClassOverrides() {
+        final Object overrides = classOverrides.get();
         assert overrides != null;
         return overrides;
     }
@@ -134,6 +134,22 @@
         NO_PERMISSIONS_INVOKER.invokeExact(method, arg);
     }
 
+    /**
+     * Set the current global scope
+     * @param global the global scope
+     */
+    public static void setGlobal(final Object global) {
+        Context.setGlobal((ScriptObject)global);
+    }
+
+    /**
+     * Get the current global scope
+     * @return the current global scope
+     */
+    public static Object getGlobal() {
+        return Context.getGlobal();
+    }
+
     static void setClassOverrides(ScriptObject overrides) {
         classOverrides.set(overrides);
     }
--- a/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Wed May 28 13:58:46 2014 +0200
+++ b/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Wed May 28 16:53:43 2014 +0200
@@ -39,16 +39,38 @@
  * Check java reflection permission for java reflective and java.lang.invoke access from scripts
  */
 final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{
+    private static final Class<?> STATEMENT_CLASS  = getBeanClass("Statement");
+    private static final Class<?> XMLENCODER_CLASS = getBeanClass("XMLEncoder");
+    private static final Class<?> XMLDECODER_CLASS = getBeanClass("XMLDecoder");
+
+    private static Class<?> getBeanClass(final String name) {
+        try {
+            return Class.forName("java.beans." + name);
+        } catch (final ClassNotFoundException cnfe) {
+            // Possible to miss this class in other profiles.
+            return null;
+        }
+    }
+
     @Override
     public boolean canLinkType(final Class<?> type) {
         return isReflectionClass(type);
     }
 
     private static boolean isReflectionClass(final Class<?> type) {
+        // Class or ClassLoader subclasses
         if (type == Class.class || ClassLoader.class.isAssignableFrom(type)) {
             return true;
         }
 
+        // check for bean reflection
+        if ((STATEMENT_CLASS != null && STATEMENT_CLASS.isAssignableFrom(type)) ||
+            (XMLENCODER_CLASS != null && XMLENCODER_CLASS.isAssignableFrom(type)) ||