Merge
diff --git a/make/build.xml b/make/build.xml
index c90cdd6..7d1f42a 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -372,6 +372,12 @@
     
     <copy file="${file.reference.jfxrt.jar}" todir="dist"/>
     
+    <condition property="jfx.prism.order" value="-Dprism.order=j2d" else=" ">
+		<not>
+            <os family="mac"/>
+        </not>
+	</condition>
+    
     <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}"/>
@@ -380,6 +386,7 @@
         <propertyref prefix="testjfx-test-sys-prop."/>
         <mapper from="testjfx-test-sys-prop.*" to="*" type="glob"/>
       </propertyset>
+      <sysproperty key="test.fork.jvm.options" value="${testjfx-test-sys-prop.test.fork.jvm.options} ${jfx.prism.order}"/>
       <classpath>
           <pathelement path="${testjfx.run.test.classpath}"/>
       </classpath>
diff --git a/make/project.properties b/make/project.properties
index 33c9478..c3ffca4 100644
--- a/make/project.properties
+++ b/make/project.properties
@@ -230,7 +230,7 @@
     ${file.reference.jemmyawtinput.jar}${path.separator}\
     ${file.reference.testng.jar}${path.separator}\
     ${nashorn.internal.tests.jar}${path.separator}\
-    ${nashorn.api.tests.jar}    
+    ${nashorn.api.tests.jar}
 
 # testjfx VM options for script tests with @fork option
 testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath}
diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index ee287a2..911f166 100644
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -41,6 +41,7 @@
 import java.util.Set;
 import java.util.concurrent.Callable;
 import javax.script.Bindings;
+import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
@@ -594,14 +595,35 @@
     }
 
     /**
-     * Make a script object mirror on given object if needed.
+     * Utilitity to convert this script object to the given type.
      *
-     * @param obj object to be wrapped
-     * @param homeGlobal global to which this object belongs
-     * @return wrapped object
+     * @param type destination type to convert to
+     * @return converted object
      */
-    public static Object wrap(final Object obj, final ScriptObject homeGlobal) {
-        return (obj instanceof ScriptObject && homeGlobal != null) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
+    public <T> T to(final Class<T> type) {
+        return inGlobal(new Callable<T>() {
+            @Override
+            public T call() {
+                return type.cast(ScriptUtils.convert(sobj, type));
+            }
+        });
+    }
+
+    /**
+     * Make a script object mirror on given object if needed. Also converts ConsString instances to Strings.
+     *
+     * @param obj object to be wrapped/converted
+     * @param homeGlobal global to which this object belongs. Not used for ConsStrings.
+     * @return wrapped/converted object
+     */
+    public static Object wrap(final Object obj, final Object homeGlobal) {
+        if(obj instanceof ScriptObject) {
+            return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj;
+        }
+        if(obj instanceof ConsString) {
+            return obj.toString();
+        }
+        return obj;
     }
 
     /**
@@ -611,7 +633,7 @@
      * @param homeGlobal global to which this object belongs
      * @return unwrapped object
      */
-    public static Object unwrap(final Object obj, final ScriptObject homeGlobal) {
+    public static Object unwrap(final Object obj, final Object homeGlobal) {
         if (obj instanceof ScriptObjectMirror) {
             final ScriptObjectMirror mirror = (ScriptObjectMirror)obj;
             return (mirror.global == homeGlobal)? mirror.sobj : obj;
@@ -627,7 +649,7 @@
      * @param homeGlobal global to which this object belongs
      * @return wrapped array
      */
-    public static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) {
+    public static Object[] wrapArray(final Object[] args, final Object homeGlobal) {
         if (args == null || args.length == 0) {
             return args;
         }
@@ -648,7 +670,7 @@
      * @param homeGlobal global to which this object belongs
      * @return unwrapped array
      */
-    public static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) {
+    public static Object[] unwrapArray(final Object[] args, final Object homeGlobal) {
         if (args == null || args.length == 0) {
             return args;
         }
diff --git a/src/jdk/nashorn/api/scripting/ScriptUtils.java b/src/jdk/nashorn/api/scripting/ScriptUtils.java
index 48045e1..29d03db 100644
--- a/src/jdk/nashorn/api/scripting/ScriptUtils.java
+++ b/src/jdk/nashorn/api/scripting/ScriptUtils.java
@@ -25,11 +25,17 @@
 
 package jdk.nashorn.api.scripting;
 
+import java.lang.invoke.MethodHandle;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
 /**
- * Utilities that are to be called from script code
+ * Utilities that are to be called from script code.
  */
 public final class ScriptUtils {
     private ScriptUtils() {}
@@ -71,4 +77,96 @@
         return func.makeSynchronizedFunction(sync);
     }
 
+    /**
+     * Make a script object mirror on given object if needed.
+     *
+     * @param obj object to be wrapped
+     * @return wrapped object
+     */
+    public static Object wrap(final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ScriptObjectMirror.wrap(obj, Context.getGlobal());
+        }
+
+        return obj;
+    }
+
+    /**
+     * Unwrap a script object mirror if needed.
+     *
+     * @param obj object to be unwrapped
+     * @return unwrapped object
+     */
+    public static Object unwrap(final Object obj) {
+        if (obj instanceof ScriptObjectMirror) {
+            return ScriptObjectMirror.unwrap(obj, Context.getGlobal());
+        }
+
+        return obj;
+    }
+
+    /**
+     * Wrap an array of object to script object mirrors if needed.
+     *
+     * @param args array to be unwrapped
+     * @return wrapped array
+     */
+    public static Object[] wrapArray(final Object[] args) {
+        if (args == null || args.length == 0) {
+            return args;
+        }
+
+        return ScriptObjectMirror.wrapArray(args, Context.getGlobal());
+    }
+
+    /**
+     * Unwrap an array of script object mirrors if needed.
+     *
+     * @param args array to be unwrapped
+     * @return unwrapped array
+     */
+    public static Object[] unwrapArray(final Object[] args) {
+        if (args == null || args.length == 0) {
+            return args;
+        }
+
+        return ScriptObjectMirror.unwrapArray(args, Context.getGlobal());
+    }
+
+    /**
+     * Convert the given object to the given type.
+     *
+     * @param obj object to be converted
+     * @param type destination type to convert to
+     * @return converted object
+     */
+    public static Object convert(final Object obj, final Object type) {
+        if (obj == null) {
+            return null;
+        }
+
+        final Class<?> clazz;
+        if (type instanceof Class) {
+            clazz = (Class<?>)type;
+        } else if (type instanceof StaticClass) {
+            clazz = ((StaticClass)type).getRepresentedClass();
+        } else {
+            throw new IllegalArgumentException("type expected");
+        }
+
+        final LinkerServices linker = Bootstrap.getLinkerServices();
+        final MethodHandle converter = linker.getTypeConverter(obj.getClass(),  clazz);
+        if (converter == null) {
+            // no supported conversion!
+            throw new UnsupportedOperationException("conversion not supported");
+        }
+
+        try {
+            return converter.invoke(obj);
+        } catch (final RuntimeException | Error e) {
+            throw e;
+        } catch (final Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
 }
diff --git a/src/jdk/nashorn/internal/codegen/Attr.java b/src/jdk/nashorn/internal/codegen/Attr.java
index 5415a06..f1ced8a 100644
--- a/src/jdk/nashorn/internal/codegen/Attr.java
+++ b/src/jdk/nashorn/internal/codegen/Attr.java
@@ -271,6 +271,7 @@
                     functionNode.addDeclaredSymbol(symbol);
                     if (varNode.isFunctionDeclaration()) {
                         newType(symbol, FunctionNode.FUNCTION_TYPE);
+                        symbol.setIsFunctionDeclaration();
                     }
                     return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
                 }
@@ -1264,12 +1265,17 @@
 
     @Override
     public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
-        return end(ensureSymbol(binaryNode.rhs().getType(), binaryNode));
+        return leaveComma(binaryNode, binaryNode.rhs());
     }
 
     @Override
     public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
-        return end(ensureSymbol(binaryNode.lhs().getType(), binaryNode));
+        return leaveComma(binaryNode, binaryNode.lhs());
+    }
+
+    private Node leaveComma(final BinaryNode commaNode, final Expression effectiveExpr) {
+        ensureTypeNotUnknown(effectiveExpr);
+        return end(ensureSymbol(effectiveExpr.getType(), commaNode));
     }
 
     @Override
diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index 206433d..f5c1fb8 100644
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -412,6 +412,8 @@
             return method;
         }
 
+        assert !type.isUnknown();
+
         /*
          * The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y"
          * or IndexNode e.g. "x[y]". Both AccessNodes and IndexNodes are
diff --git a/src/jdk/nashorn/internal/codegen/MapCreator.java b/src/jdk/nashorn/internal/codegen/MapCreator.java
index 2921ea9..8012adf 100644
--- a/src/jdk/nashorn/internal/codegen/MapCreator.java
+++ b/src/jdk/nashorn/internal/codegen/MapCreator.java
@@ -134,6 +134,10 @@
             flags |= Property.CAN_BE_UNDEFINED;
         }
 
+        if (symbol.isFunctionDeclaration()) {
+            flags |= Property.IS_FUNCTION_DECLARATION;
+        }
+
         return flags;
     }
 
diff --git a/src/jdk/nashorn/internal/ir/Symbol.java b/src/jdk/nashorn/internal/ir/Symbol.java
index 69e98ac..2906893 100644
--- a/src/jdk/nashorn/internal/ir/Symbol.java
+++ b/src/jdk/nashorn/internal/ir/Symbol.java
@@ -75,6 +75,8 @@
     public static final int IS_SPECIALIZED_PARAM = 1 << 13;
     /** Is this symbol a shared temporary? */
     public static final int IS_SHARED            = 1 << 14;
+    /** Is this a function declaration? */
+    public static final int IS_FUNCTION_DECLARATION = 1 << 15;
 
     /** Null or name identifying symbol. */
     private final String name;
@@ -360,6 +362,14 @@
     }
 
     /**
+     * Check if this symbol is a function declaration
+     * @return true if a function declaration
+     */
+    public boolean isFunctionDeclaration() {
+        return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
+    }
+
+    /**
      * Creates an unshared copy of a symbol. The symbol must be currently shared.
      * @param newName the name for the new symbol.
      * @return a new, unshared symbol.
@@ -396,6 +406,16 @@
 
 
     /**
+     * Mark this symbol as a function declaration.
+     */
+    public void setIsFunctionDeclaration() {
+        if (!isFunctionDeclaration()) {
+            trace("SET IS FUNCTION DECLARATION");
+            flags |= IS_FUNCTION_DECLARATION;
+        }
+    }
+
+    /**
      * Check if this symbol is a variable
      * @return true if variable
      */
diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java
index a0df10b..0a09370 100644
--- a/src/jdk/nashorn/internal/objects/Global.java
+++ b/src/jdk/nashorn/internal/objects/Global.java
@@ -53,19 +53,19 @@
 import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.NativeJavaPackage;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
-import jdk.nashorn.internal.runtime.arrays.ArrayData;
-import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.Scope;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.ScriptingFunctions;
 import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
+import jdk.nashorn.internal.runtime.regexp.RegExpResult;
 import jdk.nashorn.internal.scripts.JO;
 
 /**
diff --git a/src/jdk/nashorn/internal/objects/NativeObject.java b/src/jdk/nashorn/internal/objects/NativeObject.java
index 94e3bef..c7db39a 100644
--- a/src/jdk/nashorn/internal/objects/NativeObject.java
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java
@@ -60,6 +60,7 @@
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
+import jdk.nashorn.internal.runtime.linker.NashornBeansLinker;
 
 /**
  * ECMA 15.2 Object objects
@@ -729,8 +730,7 @@
             final MethodType methodType, final Object source) {
         final GuardedInvocation inv;
         try {
-            inv = linker.getGuardedInvocation(createLinkRequest(operation, methodType, source),
-                Bootstrap.getLinkerServices());
+            inv = NashornBeansLinker.getGuardedInvocation(linker, createLinkRequest(operation, methodType, source), Bootstrap.getLinkerServices());
             assert passesGuard(source, inv.getGuard());
         } catch(RuntimeException|Error e) {
             throw e;
diff --git a/src/jdk/nashorn/internal/runtime/ConsString.java b/src/jdk/nashorn/internal/runtime/ConsString.java
index 9cf5155..8f764f4 100644
--- a/src/jdk/nashorn/internal/runtime/ConsString.java
+++ b/src/jdk/nashorn/internal/runtime/ConsString.java
@@ -57,10 +57,7 @@
 
     @Override
     public String toString() {
-        if (!flat) {
-            flatten();
-        }
-        return (String) left;
+        return (String) flattened();
     }
 
     @Override
@@ -70,18 +67,19 @@
 
     @Override
     public char charAt(final int index) {
-        if (!flat) {
-            flatten();
-        }
-        return left.charAt(index);
+        return flattened().charAt(index);
     }
 
     @Override
     public CharSequence subSequence(final int start, final int end) {
+        return flattened().subSequence(start, end);
+    }
+
+    private CharSequence flattened() {
         if (!flat) {
             flatten();
         }
-        return left.subSequence(start, end);
+        return left;
     }
 
     private void flatten() {
diff --git a/src/jdk/nashorn/internal/runtime/JSType.java b/src/jdk/nashorn/internal/runtime/JSType.java
index e1b9130..5413019 100644
--- a/src/jdk/nashorn/internal/runtime/JSType.java
+++ b/src/jdk/nashorn/internal/runtime/JSType.java
@@ -88,6 +88,9 @@
     /** JavaScript compliant conversion function from Object to number */
     public static final Call TO_NUMBER = staticCall(myLookup, JSType.class, "toNumber", double.class, Object.class);
 
+    /** JavaScript compliant conversion function from Object to String */
+    public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class);
+
     /** JavaScript compliant conversion function from Object to int32 */
     public static final Call TO_INT32 = staticCall(myLookup, JSType.class, "toInt32", int.class, Object.class);
 
@@ -883,7 +886,7 @@
      */
     public static Object toJavaArray(final Object obj, final Class<?> componentType) {
         if (obj instanceof ScriptObject) {
-            return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType);
+            return ((ScriptObject)obj).getArray().asArrayOfType(componentType);
         } else if (obj instanceof JSObject) {
             final ArrayLikeIterator<?> itr = ArrayLikeIterator.arrayLikeIterator(obj);
             final int len = (int) itr.getLength();
@@ -908,6 +911,15 @@
      * @return converted Java array
      */
     public static Object convertArray(final Object[] src, final Class<?> componentType) {
+        if(componentType == Object.class) {
+            for(int i = 0; i < src.length; ++i) {
+                final Object e = src[i];
+                if(e instanceof ConsString) {
+                    src[i] = e.toString();
+                }
+            }
+        }
+
         final int l = src.length;
         final Object dst = Array.newInstance(componentType, l);
         final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
diff --git a/src/jdk/nashorn/internal/runtime/Property.java b/src/jdk/nashorn/internal/runtime/Property.java
index e735ed1..d1dbe2a 100644
--- a/src/jdk/nashorn/internal/runtime/Property.java
+++ b/src/jdk/nashorn/internal/runtime/Property.java
@@ -56,33 +56,36 @@
     public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000;
 
     /** ECMA 8.6.1 - Is this property not writable? */
-    public static final int NOT_WRITABLE     = 0b0000_0000_0001;
+    public static final int NOT_WRITABLE     = 1 << 0;
 
     /** ECMA 8.6.1 - Is this property not enumerable? */
-    public static final int NOT_ENUMERABLE   = 0b0000_0000_0010;
+    public static final int NOT_ENUMERABLE   = 1 << 1;
 
     /** ECMA 8.6.1 - Is this property not configurable? */
-    public static final int NOT_CONFIGURABLE = 0b0000_0000_0100;
+    public static final int NOT_CONFIGURABLE = 1 << 2;
 
-    private static final int MODIFY_MASK     = 0b0000_0000_1111;
+    private static final int MODIFY_MASK     = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE);
 
     /** Is this a spill property? See {@link AccessorProperty} */
-    public static final int IS_SPILL         = 0b0000_0001_0000;
+    public static final int IS_SPILL         = 1 << 3;
 
     /** Is this a function parameter? */
-    public static final int IS_PARAMETER     = 0b0000_0010_0000;
+    public static final int IS_PARAMETER     = 1 << 4;
 
     /** Is parameter accessed thru arguments? */
-    public static final int HAS_ARGUMENTS    = 0b0000_0100_0000;
+    public static final int HAS_ARGUMENTS    = 1 << 5;
 
     /** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */
-    public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000;
+    public static final int IS_ALWAYS_OBJECT = 1 << 6;
 
     /** Can this property be primitive? */
-    public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000;
+    public static final int CAN_BE_PRIMITIVE = 1 << 7;
 
     /** Can this property be undefined? */
-    public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000;
+    public static final int CAN_BE_UNDEFINED = 1 << 8;
+
+    /* Is this a function declaration property ? */
+    public static final int IS_FUNCTION_DECLARATION = 1 << 9;
 
     /** Property key. */
     private final String key;
@@ -522,4 +525,12 @@
     public boolean canBeUndefined() {
         return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
     }
+
+    /**
+     * Check whether this property represents a function declaration.
+     * @return whether this property is a function declaration or not.
+     */
+    public boolean isFunctionDeclaration() {
+        return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
+    }
 }
diff --git a/src/jdk/nashorn/internal/runtime/ScriptObject.java b/src/jdk/nashorn/internal/runtime/ScriptObject.java
index 5d1fbcd..c7c8202 100644
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -226,14 +226,23 @@
 
         for (final Property property : properties) {
             final String key = property.getKey();
-
-            if (newMap.findProperty(key) == null) {
+            final Property oldProp = newMap.findProperty(key);
+            if (oldProp == null) {
                 if (property instanceof UserAccessorProperty) {
                     final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
                     newMap = newMap.addProperty(prop);
                 } else {
                     newMap = newMap.addPropertyBind((AccessorProperty)property, source);
                 }
+            } else {
+                // See ECMA section 10.5 Declaration Binding Instantiation
+                // step 5 processing each function declaration.
+                if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
+                     if (oldProp instanceof UserAccessorProperty ||
+                         !(oldProp.isWritable() && oldProp.isEnumerable())) {
+                         throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
+                     }
+                }
             }
         }
 
diff --git a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
index f725817..0d5f68a 100644
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
+++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@@ -63,7 +63,7 @@
         final DynamicLinkerFactory factory = new DynamicLinkerFactory();
         factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
                 new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
-        factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker());
+        factory.setFallbackLinkers(new NashornBeansLinker(), new NashornBottomLinker());
         factory.setSyncOnRelink(true);
         final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
         if (relinkThreshold > -1) {
diff --git a/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java b/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java
index ccd497d..77c1618 100644
--- a/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java
@@ -72,7 +72,7 @@
                 type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass()));
 
         // Delegate to BeansLinker
-        final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethodClass).getGuardedInvocation(
+        final GuardedInvocation inv = NashornBeansLinker.getGuardedInvocation(BeansLinker.getLinkerForClass(dynamicMethodClass),
                 linkRequest.replaceArguments(newDescriptor, args), linkerServices);
         if(inv == null) {
             return null;
diff --git a/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java b/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java
index 8e40805..c42af1d 100644
--- a/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java
@@ -100,8 +100,9 @@
                 type.changeParameterType(0, adapterClass), 0);
 
         // Delegate to BeansLinker
-        final GuardedInvocation guardedInv = BeansLinker.getLinkerForClass(adapterClass).getGuardedInvocation(
-                linkRequest.replaceArguments(newDescriptor, args), linkerServices);
+        final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
+                BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
+                linkerServices);
 
         final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
         if(guardedInv == null) {
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
new file mode 100644
index 0000000..e2db2b1
--- /dev/null
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.linker;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Lookup;
+import jdk.nashorn.internal.runtime.ConsString;
+
+/**
+ * This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified
+ * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally
+ * observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add
+ * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
+ * the target method handle parameter signature is {@code Object}.
+ */
+public class NashornBeansLinker implements GuardingDynamicLinker {
+    private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class);
+
+    private final BeansLinker beansLinker = new BeansLinker();
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+        return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
+    }
+
+    /**
+     * Delegates to the specified linker but injects its linker services wrapper so that it will apply all special
+     * conversions that this class does.
+     * @param delegateLinker the linker to which the actual work is delegated to.
+     * @param linkRequest the delegated link request
+     * @param linkerServices the original link services that will be augmented with special conversions
+     * @return the guarded invocation from the delegate, possibly augmented with special conversions
+     * @throws Exception if the delegate throws an exception
+     */
+    public static GuardedInvocation getGuardedInvocation(final GuardingDynamicLinker delegateLinker, final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+        return delegateLinker.getGuardedInvocation(linkRequest, new NashornBeansLinkerServices(linkerServices));
+    }
+
+    @SuppressWarnings("unused")
+    private static Object exportArgument(final Object arg) {
+        return arg instanceof ConsString ? arg.toString() : arg;
+    }
+
+    private static class NashornBeansLinkerServices implements LinkerServices {
+        private final LinkerServices linkerServices;
+
+        NashornBeansLinkerServices(final LinkerServices linkerServices) {
+            this.linkerServices = linkerServices;
+        }
+
+        @Override
+        public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
+            final MethodHandle typed = linkerServices.asType(handle, fromType);
+
+            final MethodType handleType = handle.type();
+            final int paramCount = handleType.parameterCount();
+            assert fromType.parameterCount() == handleType.parameterCount();
+
+            MethodHandle[] filters = null;
+            for(int i = 0; i < paramCount; ++i) {
+                if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) {
+                    if(filters == null) {
+                        filters = new MethodHandle[paramCount];
+                    }
+                    filters[i] = EXPORT_ARGUMENT;
+                }
+            }
+
+            return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
+        }
+
+        private static boolean shouldConvert(final Class<?> handleType, final Class<?> fromType) {
+            return handleType == Object.class && fromType == Object.class;
+        }
+
+        @Override
+        public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
+            return linkerServices.getTypeConverter(sourceType, targetType);
+        }
+
+        @Override
+        public boolean canConvert(final Class<?> from, final Class<?> to) {
+            return linkerServices.canConvert(from, to);
+        }
+
+        @Override
+        public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
+            return linkerServices.getGuardedInvocation(linkRequest);
+        }
+
+        @Override
+        public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+            return linkerServices.compareConversion(sourceType, targetType1, targetType2);
+        }
+    }
+}
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
index 6dbcbdd..c94df15 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
@@ -33,14 +33,18 @@
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.Map;
+import java.util.HashMap;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.beans.BeansLinker;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.support.Guards;
 import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
 /**
@@ -50,7 +54,7 @@
  * setters for Java objects that couldn't be linked by any other linker, and throw appropriate ECMAScript errors for
  * attempts to invoke arbitrary Java objects as functions or constructors.
  */
-final class NashornBottomLinker implements GuardingDynamicLinker {
+final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeConverterFactory {
 
     @Override
     public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
@@ -129,6 +133,29 @@
         throw new AssertionError("unknown call type " + desc);
     }
 
+    @Override
+    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+        final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
+        return gi == null ? null : gi.asType(MH.type(targetType, sourceType));
+    }
+
+    /**
+     * Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType(Class, Class)} that doesn't
+     * care about adapting the method signature; that's done by the invoking method. Returns conversion from Object to String/number/boolean (JS primitive types).
+     * @param sourceType the source type
+     * @param targetType the target type
+     * @return a guarded invocation that converts from the source type to the target type.
+     * @throws Exception if something goes wrong
+     */
+    private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+        final MethodHandle mh = CONVERTERS.get(targetType);
+        if (mh != null) {
+            return new GuardedInvocation(mh, null);
+        }
+
+        return null;
+    }
+
     private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
         return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
     }
@@ -161,6 +188,15 @@
         throw new AssertionError("unknown call type " + desc);
     }
 
+    private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>();
+    static {
+        CONVERTERS.put(boolean.class, JSType.TO_BOOLEAN.methodHandle());
+        CONVERTERS.put(double.class, JSType.TO_NUMBER.methodHandle());
+        CONVERTERS.put(int.class, JSType.TO_INTEGER.methodHandle());
+        CONVERTERS.put(long.class, JSType.TO_LONG.methodHandle());
+        CONVERTERS.put(String.class, JSType.TO_STRING.methodHandle());
+    }
+
     private static String getArgument(final LinkRequest linkRequest) {
         final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
         if (desc.getNameTokenCount() > 2) {
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
index a760c60..27e4573 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
@@ -32,6 +32,8 @@
 import java.lang.reflect.Modifier;
 import java.util.Deque;
 import java.util.List;
+import java.util.Map;
+import javax.script.Bindings;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.ConversionComparator;
 import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -40,7 +42,11 @@
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
 import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.ScriptUtils;
 import jdk.nashorn.internal.objects.NativeArray;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -115,9 +121,14 @@
             return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE);
         }
 
-        GuardedInvocation inv = getArrayConverter(sourceType, targetType);
-        if(inv != null) {
-            return inv;
+        final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType);
+        if(arrayConverter != null) {
+            return arrayConverter;
+        }
+
+        final GuardedInvocation mirrorConverter = getMirrorConverter(sourceType, targetType);
+        if(mirrorConverter != null) {
+            return mirrorConverter;
         }
 
         return getSamTypeConverter(sourceType, targetType);
@@ -181,6 +192,18 @@
         return MH.asType(converter, converter.type().changeReturnType(type));
     }
 
+    private static GuardedInvocation getMirrorConverter(Class<?> sourceType, Class<?> targetType) {
+        // Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but
+        // it's probably better to explicitly spell out the supported target types
+        if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) {
+            if(ScriptObject.class.isAssignableFrom(sourceType)) {
+                return new GuardedInvocation(CREATE_MIRROR, null);
+            }
+            return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT);
+        }
+        return null;
+    }
+
     private static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
         return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) &&
                 JavaAdapterFactory.isAutoConvertibleFromFunction(clazz);
@@ -235,17 +258,23 @@
         return clazz == List.class || clazz == Deque.class;
     }
 
+    private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class));
     private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class));
     private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class));
 
-    private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined",
-            Boolean.TYPE, Object.class);
+    private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class);
+    private static final MethodHandle CREATE_MIRROR = findOwnMH("createMirror", Object.class, Object.class);
 
     @SuppressWarnings("unused")
     private static boolean isNashornTypeOrUndefined(final Object obj) {
         return obj instanceof ScriptObject || obj instanceof Undefined;
     }
 
+    @SuppressWarnings("unused")
+    private static Object createMirror(final Object obj) {
+        return ScriptUtils.wrap(obj);
+    }
+
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
         return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types));
     }
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
index ce60d79..72ed976 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
@@ -93,7 +93,7 @@
     }
 
     private static GuardedInvocation delegate(LinkerServices linkerServices, final LinkRequest request) throws Exception {
-        return staticClassLinker.getGuardedInvocation(request, linkerServices);
+        return NashornBeansLinker.getGuardedInvocation(staticClassLinker, request, linkerServices);
     }
 
     private static GuardedInvocation checkNullConstructor(final GuardedInvocation ctorInvocation, final Class<?> receiverClass) {
diff --git a/test/script/basic/JDK-8015355.js b/test/script/basic/JDK-8015355.js
index bc39d8d..aa1a39d 100644
--- a/test/script/basic/JDK-8015355.js
+++ b/test/script/basic/JDK-8015355.js
@@ -28,10 +28,6 @@
  * @run
  */
 
-function fail(msg) {
-    print(msg);
-}
-
 function check(callback) {
     try {
         callback();
diff --git a/test/script/basic/JDK-8027236.js b/test/script/basic/JDK-8027236.js
new file mode 100644
index 0000000..02f9e8d
--- /dev/null
+++ b/test/script/basic/JDK-8027236.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8027236: Ensure ScriptObject and ConsString aren't visible to Java
+ *
+ * @test
+ * @run
+ */
+
+// Check that ConsString is flattened
+var m = new java.util.HashMap()
+var x = "f"
+x += "oo"
+m.put(x, "bar")
+print(m.get("foo"))
+// Note: many more tests are run by the JavaExportImportTest TestNG class.
diff --git a/test/script/basic/JDK-8027236.js.EXPECTED b/test/script/basic/JDK-8027236.js.EXPECTED
new file mode 100644
index 0000000..5716ca5
--- /dev/null
+++ b/test/script/basic/JDK-8027236.js.EXPECTED
@@ -0,0 +1 @@
+bar
diff --git a/test/script/basic/JDK-8027700.js b/test/script/basic/JDK-8027700.js
new file mode 100644
index 0000000..4c5445d
--- /dev/null
+++ b/test/script/basic/JDK-8027700.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8027700: function redeclaration checks missing for declaration binding instantiation
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(this,"x", {
+        value:0,
+        writable:true,
+        enumerable:false
+})
+
+try {
+    eval("function x() {}");
+    fail("should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("TypeError expected but got " + e);
+    }
+}
+
+Object.defineProperty(this, "foo", { value:0 }) 
+try {
+    eval("function foo() {}");
+    fail("should have thrown TypeError");
+} catch (e) {
+    if (! (e instanceof TypeError)) {
+        fail("TypeError expected but got " + e);
+    }
+}
diff --git a/test/script/basic/JDK-8027753.js b/test/script/basic/JDK-8027753.js
new file mode 100644
index 0000000..2af0baa
--- /dev/null
+++ b/test/script/basic/JDK-8027753.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8027753: Support ScriptObject to JSObject, ScriptObjectMirror, Map, Bindings auto-conversion as well as explicit wrap, unwrap
+ *
+ * @test
+ * @run
+ */
+
+var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils");
+var ScriptObjectMirror = Java.type("jdk.nashorn.api.scripting.ScriptObjectMirror");
+
+var obj = { foo: 34, bar: 'hello' };
+
+var wrapped = ScriptUtils.wrap(obj);
+if (! (wrapped instanceof ScriptObjectMirror)) {
+    fail("ScriptUtils.wrap does not return a ScriptObjectMirror");
+}
+
+print("wrapped.foo = " + wrapped.foo);
+print("wrapped.bar = " + wrapped.bar);
+
+var unwrapped = ScriptUtils.unwrap(wrapped);
+if (! (unwrapped instanceof Object)) {
+    fail("ScriptUtils.unwrap does not return a ScriptObject");
+}
+
+// same object unwrapped?
+print(unwrapped === obj);
diff --git a/test/script/basic/JDK-8027753.js.EXPECTED b/test/script/basic/JDK-8027753.js.EXPECTED
new file mode 100644
index 0000000..30a8779
--- /dev/null
+++ b/test/script/basic/JDK-8027753.js.EXPECTED
@@ -0,0 +1,3 @@
+wrapped.foo = 34
+wrapped.bar = hello
+true
diff --git a/test/script/basic/JDK-8027828.js b/test/script/basic/JDK-8027828.js
new file mode 100644
index 0000000..ab60938
--- /dev/null
+++ b/test/script/basic/JDK-8027828.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8027828: ClassCastException when converting return value of a Java method to boolean
+ *
+ * @test
+ * @run
+ */
+
+var x = new java.util.HashMap()
+x.put('test', new java.io.File('test'))
+if (x.get("test")) {
+  print('Found!')
+}
diff --git a/test/script/basic/JDK-8027828.js.EXPECTED b/test/script/basic/JDK-8027828.js.EXPECTED
new file mode 100644
index 0000000..7a8c9ed
--- /dev/null
+++ b/test/script/basic/JDK-8027828.js.EXPECTED
@@ -0,0 +1 @@
+Found!
diff --git a/test/script/basic/JDK-8028020.js b/test/script/basic/JDK-8028020.js
new file mode 100644
index 0000000..4dfa0ca
--- /dev/null
+++ b/test/script/basic/JDK-8028020.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8028020: Function parameter as last expression in comma in return value causes bad type calculation
+ *
+ * @test
+ * @run
+ */
+
+function f(x) {
+    return 1, x
+}
+
+function g(x, y) {
+    return x, y
+}
+
+print(f("'1, x' works."))
+print(g(42, "'x, y' works too."))
diff --git a/test/script/basic/JDK-8028020.js.EXPECTED b/test/script/basic/JDK-8028020.js.EXPECTED
new file mode 100644
index 0000000..816a21c
--- /dev/null
+++ b/test/script/basic/JDK-8028020.js.EXPECTED
@@ -0,0 +1,2 @@
+'1, x' works.
+'x, y' works too.
diff --git a/test/script/basic/convert.js b/test/script/basic/convert.js
new file mode 100644
index 0000000..8d11d12
--- /dev/null
+++ b/test/script/basic/convert.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Tests for convert method of ScriptUtils.
+ *
+ * @test
+ * @run
+ */
+
+var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils");
+obj = { valueOf: function() { print("hello"); return 43.3; } };
+
+// object to double
+print(ScriptUtils.convert(obj, java.lang.Number.class));
+
+// array to List
+var arr = [3, 44, 23, 33];
+var list = ScriptUtils.convert(arr, java.util.List.class);
+print(list instanceof java.util.List)
+print(list);
+
+// object to Map
+obj = { foo: 333, bar: 'hello'};
+var map = ScriptUtils.convert(obj, java.util.Map.class);
+print(map instanceof java.util.Map);
+for (m in map) {
+   print(m + " " + map[m]);
+}
+
+// object to String
+obj = { toString: function() { print("in toString"); return "foo" } };
+print(ScriptUtils.convert(obj, java.lang.String.class));
+
+// array to Java array
+var jarr = ScriptUtils.convert(arr, Java.type("int[]"));
+print(jarr instanceof Java.type("int[]"));
+for (i in jarr) {
+    print(jarr[i]);
+}
+
diff --git a/test/script/basic/convert.js.EXPECTED b/test/script/basic/convert.js.EXPECTED
new file mode 100644
index 0000000..e83faeb
--- /dev/null
+++ b/test/script/basic/convert.js.EXPECTED
@@ -0,0 +1,14 @@
+hello
+43.3
+true
+[3, 44, 23, 33]
+true
+foo 333
+bar hello
+in toString
+foo
+true
+3
+44
+23
+33
diff --git a/test/script/jfx.js b/test/script/jfx.js
index 26f9787..5962b5d 100644
--- a/test/script/jfx.js
+++ b/test/script/jfx.js
@@ -37,13 +37,24 @@
 var Scene                = Java.type("javafx.scene.Scene");

 var Stage                = Java.type("javafx.stage.Stage");

 var File                 = Java.type("java.io.File");

-var Timer                = Java.type("java.util.Timer");

-var TimerTask            = Java.type("java.util.TimerTask");

 var OSInfo               = Java.type("sun.awt.OSInfo");

 var OSType               = Java.type("sun.awt.OSInfo.OSType");

 var StringBuffer         = Java.type("java.lang.StringBuffer");

+var Paint                = Java.type("javafx.scene.paint.Paint");

+var Color                = Java.type("javafx.scene.paint.Color");

+var Image                = Java.type("javafx.scene.image.Image");

+var Canvas               = Java.type("javafx.scene.canvas.Canvas");

+var BorderPane           = Java.type("javafx.scene.layout.BorderPane");

+var StackPane            = Java.type("javafx.scene.layout.StackPane");

+var StrokeLineCap        = Java.type("javafx.scene.shape.StrokeLineCap");

+var Platform             = Java.type("javafx.application.Platform");

+var Runnable             = Java.type("java.lang.Runnable");

+var RunnableExtend       = Java.extend(Runnable);

+var AnimationTimer       = Java.type("javafx.animation.AnimationTimer");

+var AnimationTimerExtend = Java.extend(AnimationTimer);

+var Timer                = Java.type("java.util.Timer");

+var TimerTask            = Java.type("java.util.TimerTask");

 

-var WAIT = 2000;

 var TESTNAME = "test";

 var fsep = System.getProperty("file.separator");

 

@@ -53,14 +64,16 @@
         run: function run() {

             var tmpdir = System.getProperty("java.io.tmpdir");

             var timenow = (new Date()).getTime();

-            makeScreenShot(tmpdir + fsep + "screenshot" + timenow +".png");

-            var dupImg = isDuplicateImages(tmpdir + fsep + "screenshot" + timenow +".png", __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden");

-            (new File(mpdir + fsep + "screenshot" + timenow +".png")).delete();

-            if (!dupImg) System.err.println("ERROR: screenshot does not match golden image");

+            var scrShotTmp = tmpdir + fsep + "screenshot" + timenow +".png";

+            var goldenImageDir = __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden";

+            makeScreenShot(scrShotTmp);

+            var dupImg = isDuplicateImages(scrShotTmp, goldenImageDir);

+            (new File(scrShotTmp)).delete();

+            if (!dupImg) System.err.println("ERROR: screenshot does not match the golden image");

             exit(0);

         }

     };

-    raceTimer.schedule(timerTask, WAIT);

+    raceTimer.schedule(timerTask, 100);

 }

 

 function makeScreenShot(shootToImg) {

@@ -70,10 +83,10 @@
    imageJemmy.save(shootToImg);

 }

 

-function isDuplicateImages(file1, file2) {

-    var f1 = new File(file1);

+function isDuplicateImages(screenShot, goldenDir) {

+    var f1 = new File(screenShot);

     var f2;

-    var sb = new StringBuffer(file2);

+    var sb = new StringBuffer(goldenDir);

     if (OSInfo.getOSType() == OSType.WINDOWS) {

         f2 = new File(sb.append(fsep + "windows.png").toString());

     } else if (OSInfo.getOSType() == OSType.LINUX) {

@@ -81,8 +94,6 @@
     } else if (OSInfo.getOSType() == OSType.MACOSX) {

         f2 = new File(sb.append(fsep + "macosx.png").toString());

     }

-    print(f1.getAbsolutePath());

-    print(f2.getAbsolutePath());

     if (f1.exists() && f2.exists()) {

         var image1 = new AWTImage(PNGDecoder.decode(f1.getAbsolutePath()));

         var image2 = new AWTImage(PNGDecoder.decode(f2.getAbsolutePath()));

diff --git a/test/script/jfx/flyingimage.js b/test/script/jfx/flyingimage.js
index 4cf3f7f..844a0fc 100644
--- a/test/script/jfx/flyingimage.js
+++ b/test/script/jfx/flyingimage.js
@@ -31,15 +31,6 @@
 

 TESTNAME = "flyingimage";

 

-var Image                = Java.type("javafx.scene.image.Image");

-var Color                = Java.type("javafx.scene.paint.Color");

-var Canvas               = Java.type("javafx.scene.canvas.Canvas");

-var BorderPane           = Java.type("javafx.scene.layout.BorderPane");

-var StackPane            = Java.type("javafx.scene.layout.StackPane");

-var Font                 = Java.type("javafx.scene.text.Font");

-var FontSmoothingType    = Java.type("javafx.scene.text.FontSmoothingType");

-var Text                 = Java.type("javafx.scene.text.Text");

-

 var WIDTH = 800;

 var HEIGHT = 600;

 var canvas = new Canvas(WIDTH, HEIGHT);

@@ -48,10 +39,9 @@
 }

 var imageUrl = fileToURL(__DIR__ + "flyingimage/flyingimage.png");

 var img = new Image(imageUrl);

-var font = new Font("Arial", 16);

-var t = 0;

 var isFrameRendered = false;

 function renderFrame() {

+    var t = frame;

     var gc = canvas.graphicsContext2D;

     gc.setFill(Color.web("#cccccc"));

     gc.fillRect(0, 0, WIDTH, HEIGHT);

@@ -61,7 +51,7 @@
     var c = 200;

     var msc= 0.5 * HEIGHT / img.height;

     var sp0 = 0.003;

-    for (var h = 0; h < c; h++, t++) {

+    for (var h = 0; h < c; h++) {

         gc.setTransform(1, 0, 0, 1, 0, 0);

         var yh = h / (c - 1);

         gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh));

@@ -69,15 +59,26 @@
         gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI));

         gc.scale(sc, sc);

         gc.drawImage(img, -img.width / 2, -img.height / 2);

-     }

+    }

     gc.setTransform(1, 0, 0, 1, 0, 0);

     isFrameRendered = true;

 }

 var stack = new StackPane();

 var pane = new BorderPane();

-

 pane.setCenter(canvas);

 stack.getChildren().add(pane);

 $STAGE.scene = new Scene(stack);

-renderFrame();

-checkImageAndExit();

+var frame = 0;

+var timer = new AnimationTimerExtend() {

+    handle: function handle(now) {

+        if (frame < 200) {

+            renderFrame();

+            frame++;

+        } else {

+            checkImageAndExit();        

+            timer.stop();

+        }

+    }

+};

+timer.start();

+ 

diff --git a/test/script/jfx/flyingimage/flyingimage.png b/test/script/jfx/flyingimage/flyingimage.png
index ecd98a1..afc44dd 100644
--- a/test/script/jfx/flyingimage/flyingimage.png
+++ b/test/script/jfx/flyingimage/flyingimage.png
Binary files differ
diff --git a/test/script/jfx/flyingimage/golden/linux.png b/test/script/jfx/flyingimage/golden/linux.png
index 4f67885..4a668a6 100644
--- a/test/script/jfx/flyingimage/golden/linux.png
+++ b/test/script/jfx/flyingimage/golden/linux.png
Binary files differ
diff --git a/test/script/jfx/flyingimage/golden/macosx.png b/test/script/jfx/flyingimage/golden/macosx.png
index cb15321..ba72fe6 100644
--- a/test/script/jfx/flyingimage/golden/macosx.png
+++ b/test/script/jfx/flyingimage/golden/macosx.png
Binary files differ
diff --git a/test/script/jfx/flyingimage/golden/windows.png b/test/script/jfx/flyingimage/golden/windows.png
index e389714..e47ae4d 100644
--- a/test/script/jfx/flyingimage/golden/windows.png
+++ b/test/script/jfx/flyingimage/golden/windows.png
Binary files differ
diff --git a/test/script/jfx/kaleidoscope.js b/test/script/jfx/kaleidoscope.js
index a932c51..4430ff0 100644
--- a/test/script/jfx/kaleidoscope.js
+++ b/test/script/jfx/kaleidoscope.js
@@ -30,13 +30,6 @@
  */

 

 TESTNAME = "kaleidoscope";

-WAIT = 4000;

-

-var Paint                = Java.type("javafx.scene.paint.Paint");

-var Canvas               = Java.type("javafx.scene.canvas.Canvas");

-var BorderPane           = Java.type("javafx.scene.layout.BorderPane");

-var StackPane            = Java.type("javafx.scene.layout.StackPane");

-var StrokeLineCap        = Java.type("javafx.scene.shape.StrokeLineCap");

         

 var WIDTH = 800;

 var HEIGHT = 600;

@@ -56,26 +49,28 @@
 var r,e;

 var fade;

 var prv_x,prv_y,prv_x2,prv_y2;

+var isFrameRendered = false;

 

 function renderFrame() {

-	a=0.2*angle;

-	b=0.7*angle;

-	r=0;

-	fade=32;

-	for(var i=0;i<6;i++)

-		{

-		c[i]=1.0/(i+1)/2;

-		d[i]=1.0/(i+1)/2;

-		}

-	radius=Math.round((WIDTH+HEIGHT)/8);

-	e=radius*0.2;

-	p_x=Math.round(WIDTH/2);

-	p_y=Math.round(HEIGHT/2);

-	x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);

-	y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);

-    for (i = 0; i < 800; i++) {

-        anim();

+	if (!isFrameRendered) {

+        a=0.2*angle;

+		b=0.7*angle;

+		r=0;

+		fade=32;

+		for(var i=0;i<6;i++)

+			{

+			c[i]=1.0/(i+1)/2;

+			d[i]=1.0/(i+1)/2;

+			}

+		radius=Math.round((WIDTH+HEIGHT)/8);

+		e=radius*0.2;

+		p_x=Math.round(WIDTH/2);

+		p_y=Math.round(HEIGHT/2);

+		x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);

+		y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);

+        isFrameRendered = true;

     }

+    anim();

 }

 

 function anim() {

@@ -154,9 +149,19 @@
 

 var stack = new StackPane();

 var pane = new BorderPane();

-

 pane.setCenter(canvas);

 stack.getChildren().add(pane);

 $STAGE.scene = new Scene(stack);

-renderFrame();

-checkImageAndExit();
\ No newline at end of file
+var frame = 0;

+var timer = new AnimationTimerExtend() {

+    handle: function handle(now) {

+        if (frame < 800) {

+            renderFrame();

+            frame++;

+        } else {

+            checkImageAndExit();

+            timer.stop();

+        }

+    }

+};

+timer.start();

diff --git a/test/script/jfx/kaleidoscope/golden/linux.png b/test/script/jfx/kaleidoscope/golden/linux.png
index ccc92fe..4d7e81a 100644
--- a/test/script/jfx/kaleidoscope/golden/linux.png
+++ b/test/script/jfx/kaleidoscope/golden/linux.png
Binary files differ
diff --git a/test/script/jfx/kaleidoscope/golden/macosx.png b/test/script/jfx/kaleidoscope/golden/macosx.png
index 1adeb1e..64d9499 100644
--- a/test/script/jfx/kaleidoscope/golden/macosx.png
+++ b/test/script/jfx/kaleidoscope/golden/macosx.png
Binary files differ
diff --git a/test/script/jfx/kaleidoscope/golden/windows.png b/test/script/jfx/kaleidoscope/golden/windows.png
index 84ee37c..4d7e81a 100644
--- a/test/script/jfx/kaleidoscope/golden/windows.png
+++ b/test/script/jfx/kaleidoscope/golden/windows.png
Binary files differ
diff --git a/test/script/jfx/spread.js b/test/script/jfx/spread.js
new file mode 100644
index 0000000..4a8f38c
--- /dev/null
+++ b/test/script/jfx/spread.js
@@ -0,0 +1,222 @@
+/*

+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.

+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

+ * 

+ * This code is free software; you can redistribute it and/or modify it

+ * under the terms of the GNU General Public License version 2 only, as

+ * published by the Free Software Foundation.

+ * 

+ * This code is distributed in the hope that it will be useful, but WITHOUT

+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or

+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License

+ * version 2 for more details (a copy is included in the LICENSE file that

+ * accompanied this code).

+ * 

+ * You should have received a copy of the GNU General Public License version

+ * 2 along with this work; if not, write to the Free Software Foundation,

+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

+ * 

+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

+ * or visit www.oracle.com if you need additional information or have any

+ * questions.

+ */

+

+/**

+ * Testing JavaFX canvas run by Nashorn.

+ *

+ * @test/nocompare

+ * @run

+ * @fork

+ */

+ 

+TESTNAME = "spread";

+

+var WIDTH = 800;

+var HEIGHT = 600;

+var canvas = new Canvas(WIDTH, HEIGHT);

+var context = canvas.graphicsContext2D;

+

+/* "Spread" tech demo of canvas by Tom Theisen

+ *

+ * This will animate a sequence of branch structures in a canvas element.

+ * Each frame, a new direction is calculated, similar to the last frame.

+ */

+

+var start_width = 20;           // starting width of each branch

+var frame_time = 30;            // milliseconds per frame

+var straighten_factor = 0.95;   // value from 0 to 1, factor applied to direction_offset every frame

+var curviness = 0.2;            // amount of random direction change each frame

+

+var color_speed = 0.03;     // speed at which colors change when cycling is enabled

+var branch_shrink = 0.95;   // factor by which branches shrink every frame

+var min_width = 1;          // minimum WIDTH for branch, after which they are discontinued

+var branch_opacity = 0.4;   // opacity of lines drawn

+var branch_count = 3;       // branch count per tree

+var branch_bud_size = 0.5;  // ratio of original branch size at which branch will split

+var branch_bud_angle = 1;   // angle offset for split branch;

+

+var paper;                  // reference to graphics context

+var branches = Object();    // linked list of active branches

+var color_styles = [];      // pre-computed list of colors as styles. format: (r,g,b,a)    

+var direction_offset = 0;   // current direction offset in radians.  this is applied to all branches.

+var frame = 0;              // frame counter

+var timespent = 0;          // total time spent so far, used to calculate average frame render duration

+var frameratespan;          // html span element for updating performance number

+

+// preferences object, contains an attribute for each user setting

+var prefs = {

+    wrap: true,             // causes branches reaching edge of viewable area to appear on opposite side

+    fade: false,             // fade existing graphics on each frame

+    cycle: true,            // gradually change colors each frame

+    new_branch_frames: 20    // number of frames elapsed between each auto-generated tree

+};

+

+// create tree at the specified position with number of branches

+function create_tree(branches, start_width, position, branch_count) {

+    var angle_offset = Math.PI * 2 / branch_count;

+    for (var i = 0; i < branch_count; ++i) {

+        branch_add(branches, new Branch(position, angle_offset * i, start_width));

+    }

+}

+

+// add branch to collection

+function branch_add(branches, branch) {

+    branch.next = branches.next;

+    branches.next = branch;

+}

+

+// get the coordinates for the position of a new tree

+// use the center of the canvas

+function get_new_tree_center(width, height) {

+    return {

+        x: 0.5 * width, 

+        y: 0.5 * height 

+    };

+}

+

+// Branch constructor

+// position has x and y properties

+// direction is in radians

+function Branch(position, direction, width) {

+    this.x = position.x;

+    this.y = position.y;

+    this.width = width;

+    this.original_width = width;

+    this.direction = direction;

+}

+

+// update position, direction and width of a particular branch

+function branch_update(branches, branch, paper) {

+    paper.beginPath();

+    paper.lineWidth = branch.width;

+    paper.moveTo(branch.x, branch.y);

+    

+    branch.width *= branch_shrink;

+    branch.direction += direction_offset;

+    branch.x += Math.cos(branch.direction) * branch.width;

+    branch.y += Math.sin(branch.direction) * branch.width;

+    

+    paper.lineTo(branch.x, branch.y);

+    paper.stroke();

+    

+    if (prefs.wrap) wrap_branch(branch, WIDTH, HEIGHT);

+

+    if (branch.width < branch.original_width * branch_bud_size) {

+        branch.original_width *= branch_bud_size;

+        branch_add(branches, new Branch(branch, branch.direction + 1, branch.original_width));

+    }

+}

+

+function draw_frame() {

+    if (prefs.fade) {

+        paper.fillRect(0, 0, WIDTH, HEIGHT);

+    }

+

+    if (prefs.cycle) {

+        paper.setStroke(Paint.valueOf(color_styles[frame % color_styles.length]));

+    }

+

+    if (frame++ % prefs.new_branch_frames == 0) {

+        create_tree(branches, start_width, get_new_tree_center(WIDTH, HEIGHT), branch_count);

+    }

+    

+    direction_offset += (0.35 + (frame % 200) * 0.0015) * curviness - curviness / 2;

+    direction_offset *= straighten_factor;

+    

+    var branch = branches;

+    var prev_branch = branches;

+    while (branch = branch.next) {

+        branch_update(branches, branch, paper);

+        

+        if (branch.width < min_width) {

+            // remove branch from list

+            prev_branch.next = branch.next;

+        }

+        

+        prev_branch = branch;

+    }

+}

+

+// constrain branch position to visible area by "wrapping" from edge to edge

+function wrap_branch(branch, WIDTH, HEIGHT) {

+    branch.x = positive_mod(branch.x, WIDTH);

+    branch.y = positive_mod(branch.y, HEIGHT);

+}

+

+// for a < 0, b > 0, javascript returns a negative number for a % b

+// this is a variant of the % operator that adds b to the result in this case

+function positive_mod(a, b) {

+    // ECMA 262 11.5.3: Applying the % Operator 

+    // remainder operator does not convert operands to integers,

+    // although negative results are possible

+

+    return ((a % b) + b) % b;

+}

+

+// pre-compute color styles that will be used for color cycling

+function populate_colors(color_speed, color_styles, branch_opacity) {

+    // used in calculation of RGB values

+    var two_thirds_pi = Math.PI * 2 / 3;

+    var four_thirds_pi = Math.PI * 4 / 3;

+    var two_pi = Math.PI * 2;

+

+    // hue does represent hue, but not in the conventional HSL scheme

+    for(var hue = 0; hue < two_pi; hue += color_speed) {

+        var r = Math.floor(Math.sin(hue) * 128 + 128);

+        var g = Math.floor(Math.sin(hue + two_thirds_pi) * 128 + 128);

+        var b = Math.floor(Math.sin(hue + four_thirds_pi) * 128 + 128);

+        color = "rgba(" + [r, g, b, branch_opacity].join() + ")";

+

+        color_styles.push(color);

+    }

+}

+

+// apply initial settings to canvas object

+function setup_canvas() {

+    paper = canvas.graphicsContext2D;

+    paper.setFill(Paint.valueOf('rgb(0, 0, 0)'));

+    paper.fillRect(0, 0, WIDTH, HEIGHT);

+    paper.setFill(Paint.valueOf("rgba(0, 0, 0, 0.005)"));

+    paper.setStroke(Paint.valueOf("rgba(128, 128, 64, " + String(branch_opacity) + ")"));

+}

+

+populate_colors(color_speed, color_styles, branch_opacity);

+setup_canvas();

+

+var stack = new StackPane();

+var pane = new BorderPane();

+pane.setCenter(canvas);

+stack.getChildren().add(pane);

+$STAGE.scene = new Scene(stack);

+var timer = new AnimationTimerExtend() {

+    handle: function handle(now) {

+        if (frame < 200) {

+		    draw_frame();

+        } else {

+            checkImageAndExit();

+            timer.stop();

+        }

+    }

+};

+timer.start();

+

diff --git a/test/script/jfx/spread/golden/linux.png b/test/script/jfx/spread/golden/linux.png
new file mode 100644
index 0000000..fc535a4
--- /dev/null
+++ b/test/script/jfx/spread/golden/linux.png
Binary files differ
diff --git a/test/script/jfx/spread/golden/macosx.png b/test/script/jfx/spread/golden/macosx.png
new file mode 100644
index 0000000..c288162
--- /dev/null
+++ b/test/script/jfx/spread/golden/macosx.png
Binary files differ
diff --git a/test/script/jfx/spread/golden/windows.png b/test/script/jfx/spread/golden/windows.png
new file mode 100644
index 0000000..fc535a4
--- /dev/null
+++ b/test/script/jfx/spread/golden/windows.png
Binary files differ
diff --git a/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java b/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java
new file mode 100644
index 0000000..1eadfb7
--- /dev/null
+++ b/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.JSObject;
+import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ConsStringTest {
+    private static ScriptEngine e = null;
+
+    public static void main(final String[] args) {
+        TestNG.main(args);
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws ScriptException {
+        e = new ScriptEngineManager().getEngineByName("nashorn");
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        e = null;
+    }
+
+    @Test
+    public void testConsStringFlattening() throws ScriptException {
+        final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
+        final Map<Object, Object> m = new HashMap<>();
+        b.put("m", m);
+        e.eval("var x = 'f'; x += 'oo'; var y = 'b'; y += 'ar'; m.put(x, y)");
+        assertEquals("bar", m.get("foo"));
+    }
+
+    @Test
+    public void testConsStringFromMirror() throws ScriptException {
+        final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
+        final Map<Object, Object> m = new HashMap<>();
+        e.eval("var x = 'f'; x += 'oo'; var obj = {x: x};");
+        assertEquals("foo", ((JSObject)b.get("obj")).getMember("x"));
+    }
+
+    @Test
+    public void testArrayConsString() throws ScriptException {
+        final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
+        final ArrayHolder h = new ArrayHolder();
+        b.put("h", h);
+        e.eval("var x = 'f'; x += 'oo'; h.array = [x];");
+        assertEquals(1, h.array.length);
+        assertEquals("foo", h.array[0]);
+    }
+
+
+    public static class ArrayHolder {
+        private Object[] array;
+
+        public void setArray(Object[] array) {
+            this.array = array;
+        }
+
+        public Object[] getArray() {
+            return array;
+        }
+    }
+}
diff --git a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
index 99207de..55aacb3 100644
--- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
@@ -523,6 +523,18 @@
         assertEquals(sw.toString(), println("34 true hello"));
     }
 
+    @Test
+    public void scriptObjectAutoConversionTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        e.eval("obj = { foo: 'hello' }");
+        e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.Window"));
+        assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
+        assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello");
+        assertEquals(e.eval("Window.funcMap(obj)"), "hello");
+        assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
+    }
+
     private static final String LINE_SEPARATOR = System.getProperty("line.separator");
 
     // Returns String that would be the result of calling PrintWriter.println
diff --git a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java
index 6c35ee4..544f4ea 100644
--- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java
@@ -26,6 +26,7 @@
 package jdk.nashorn.api.scripting;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
@@ -227,4 +228,28 @@
         final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject();
         assertTrue(newObj instanceof ScriptObjectMirror);
     }
+
+    @Test
+    public void conversionTest() throws ScriptException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final ScriptObjectMirror arr = (ScriptObjectMirror)e.eval("[33, 45, 23]");
+        final int[] intArr = arr.to(int[].class);
+        assertEquals(intArr[0], 33);
+        assertEquals(intArr[1], 45);
+        assertEquals(intArr[2], 23);
+
+        final List<?> list = arr.to(List.class);
+        assertEquals(list.get(0), 33);
+        assertEquals(list.get(1), 45);
+        assertEquals(list.get(2), 23);
+
+        ScriptObjectMirror obj = (ScriptObjectMirror)e.eval(
+            "({ valueOf: function() { return 42 } })");
+        assertEquals(Double.valueOf(42.0), obj.to(Double.class));
+
+        obj = (ScriptObjectMirror)e.eval(
+            "({ toString: function() { return 'foo' } })");
+        assertEquals("foo", obj.to(String.class));
+    }
 }
diff --git a/test/src/jdk/nashorn/api/scripting/Window.java b/test/src/jdk/nashorn/api/scripting/Window.java
index bde2394..510c5da 100644
--- a/test/src/jdk/nashorn/api/scripting/Window.java
+++ b/test/src/jdk/nashorn/api/scripting/Window.java
@@ -25,6 +25,9 @@
 
 package jdk.nashorn.api.scripting;
 
+import java.util.Map;
+import javax.script.Bindings;
+
 public class Window {
 
     private String location = "http://localhost:8080/window";
@@ -63,4 +66,20 @@
         System.out.println("window.setTimeout: " + delay + ", code: " + code);
         return 0;
     }
+
+    public static Object funcJSObject(final JSObject jsobj) {
+        return jsobj.getMember("foo");
+    }
+
+    public static Object funcScriptObjectMirror(final ScriptObjectMirror sobj) {
+        return sobj.get("foo");
+    }
+
+    public static Object funcMap(final Map<?,?> map) {
+        return map.get("foo");
+    }
+
+    public static Object funcBindings(final Bindings bindings) {
+        return bindings.get("foo");
+    }
 }