changeset 132:5759f600fcf7 jdk8-b82

8009559: clean up method handle lookup code. Reviewed-by: ahgross, jlaskey, attila, sundar
author sundar
date Sat, 09 Mar 2013 21:49:32 +0530
parents 3d57f57acd9c
children c54e218333be 053d7c55dc82
files buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java make/java.security.override src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java src/jdk/internal/dynalink/beans/CheckRestrictedPackageInternal.java src/jdk/internal/dynalink/beans/FacetIntrospector.java src/jdk/internal/dynalink/beans/RestrictedPackageTester.java src/jdk/internal/dynalink/beans/SafeUnreflector.java src/jdk/internal/dynalink/beans/SafeUnreflectorImpl.java src/jdk/internal/dynalink/beans/SandboxClassLoader.java src/jdk/internal/dynalink/beans/StaticClassLinker.java src/jdk/internal/dynalink/beans/sandbox/Unreflector.java src/jdk/nashorn/internal/codegen/CompilerConstants.java src/jdk/nashorn/internal/codegen/FunctionSignature.java src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java src/jdk/nashorn/internal/codegen/RuntimeCallSite.java src/jdk/nashorn/internal/lookup/Lookup.java src/jdk/nashorn/internal/lookup/MethodHandleFactory.java src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java src/jdk/nashorn/internal/objects/Global.java src/jdk/nashorn/internal/objects/NativeArguments.java src/jdk/nashorn/internal/objects/NativeBoolean.java src/jdk/nashorn/internal/objects/NativeError.java src/jdk/nashorn/internal/objects/NativeJSAdapter.java src/jdk/nashorn/internal/objects/NativeNumber.java src/jdk/nashorn/internal/objects/NativeStrictArguments.java src/jdk/nashorn/internal/objects/NativeString.java src/jdk/nashorn/internal/objects/PrototypeObject.java src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java src/jdk/nashorn/internal/runtime/AccessorProperty.java src/jdk/nashorn/internal/runtime/Context.java src/jdk/nashorn/internal/runtime/FindProperty.java src/jdk/nashorn/internal/runtime/GlobalFunctions.java src/jdk/nashorn/internal/runtime/ScriptFunction.java src/jdk/nashorn/internal/runtime/ScriptFunctionData.java src/jdk/nashorn/internal/runtime/ScriptObject.java src/jdk/nashorn/internal/runtime/ScriptingFunctions.java src/jdk/nashorn/internal/runtime/SetMethodCreator.java src/jdk/nashorn/internal/runtime/SpillProperty.java src/jdk/nashorn/internal/runtime/Undefined.java src/jdk/nashorn/internal/runtime/UserAccessorProperty.java src/jdk/nashorn/internal/runtime/WithObject.java src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java src/jdk/nashorn/internal/runtime/linker/Lookup.java src/jdk/nashorn/internal/runtime/linker/MethodHandleFactory.java src/jdk/nashorn/internal/runtime/linker/MethodHandleFunctionality.java src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java src/jdk/nashorn/internal/runtime/linker/NashornGuards.java src/jdk/nashorn/internal/runtime/linker/NashornLinker.java src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java test/script/currently-failing/JDK-8006529.js test/script/trusted/JDK-8006529.js
diffstat 57 files changed, 2154 insertions(+), 1825 deletions(-) [+]
line wrap: on
line diff
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java	Sat Mar 09 21:49:32 2013 +0530
@@ -28,12 +28,12 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.reflect.Method;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.objects.PrototypeObject;
 import jdk.nashorn.internal.objects.ScriptFunctionImpl;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.linker.Lookup;
 
 /**
  * String constants used for code generation/instrumentation.
--- a/make/java.security.override	Wed Mar 06 22:38:18 2013 +0530
+++ b/make/java.security.override	Sat Mar 09 21:49:32 2013 +0530
@@ -11,4 +11,4 @@
 # passed to checkPackageAccess unless the
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.,jdk.nashorn.internal.ir., jdk.nashorn.internal.codegen., jdk.nashorn.internal.parser.
+package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.,jdk.nashorn.internal.ir., jdk.nashorn.internal.codegen., jdk.nashorn.internal.lookup., jdk.nashorn.internal.parser.
--- a/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/internal/dynalink/beans/CheckRestrictedPackage.java	Sat Mar 09 21:49:32 2013 +0530
@@ -84,26 +84,55 @@
 package jdk.internal.dynalink.beans;
 
 import java.lang.reflect.Modifier;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 
 /**
- * A utility class to check whether a given class is in a package with restricted access e.g. "sun.*" etc. See
- * {@link CheckRestrictedPackageInternal} for implementation details.
+ * A utility class to check whether a given class is in a package with restricted access e.g. "sun.*" etc.
  */
 class CheckRestrictedPackage {
+    private static final AccessControlContext NO_PERMISSIONS_CONTEXT = createNoPermissionsContext();
+
     /**
      * Returns true if the class is either not public, or it resides in a package with restricted access.
      * @param clazz the class to test
      * @return true if the class is either not public, or it resides in a package with restricted access.
      */
     static boolean isRestrictedClass(Class<?> clazz) {
-        return !Modifier.isPublic(clazz.getModifiers()) ||
-                (System.getSecurityManager() != null && isRestrictedPackage(clazz.getPackage()));
+        if(!Modifier.isPublic(clazz.getModifiers())) {
+            // Non-public classes are always restricted
+            return true;
+        }
+        final SecurityManager sm = System.getSecurityManager();
+        if(sm == null) {
+            // No further restrictions if we don't have a security manager
+            return false;
+        }
+        final String name = clazz.getName();
+        final int i = name.lastIndexOf('.');
+        if (i == -1) {
+            // Classes in default package are never restricted
+            return false;
+        }
+        // Do a package access check from within an access control context with no permissions
+        try {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                @Override
+                public Void run() {
+                    sm.checkPackageAccess(name.substring(0, i));
+                    return null;
+                }
+            }, NO_PERMISSIONS_CONTEXT);
+        } catch(SecurityException e) {
+            return true;
+        }
+        return false;
     }
 
-    private static boolean isRestrictedPackage(Package pkg) {
-        // Note: we broke out the actual implementation into CheckRestrictedPackageInternal, so we only load it when
-        // needed - that is, if we need to check a non-public class with a non-null package, in presence of a security
-        // manager.
-        return pkg == null ? false : CheckRestrictedPackageInternal.isRestrictedPackageName(pkg.getName());
+    private static AccessControlContext createNoPermissionsContext() {
+        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
     }
 }
--- a/src/jdk/internal/dynalink/beans/CheckRestrictedPackageInternal.java	Wed Mar 06 22:38:18 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file, and Oracle licenses the original version of this file under the BSD
- * license:
- */
-/*
-   Copyright 2009-2013 Attila Szegedi
-
-   Licensed under both the Apache License, Version 2.0 (the "Apache License")
-   and the BSD License (the "BSD License"), with licensee being free to
-   choose either of the two at their discretion.
-
-   You may not use this file except in compliance with either the Apache
-   License or the BSD License.
-
-   If you choose to use this file in compliance with the Apache License, the
-   following notice applies to you:
-
-       You may obtain a copy of the Apache License at
-
-           http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing, software
-       distributed under the License is distributed on an "AS IS" BASIS,
-       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-       implied. See the License for the specific language governing
-       permissions and limitations under the License.
-
-   If you choose to use this file in compliance with the BSD License, the
-   following notice applies to you:
-
-       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 the copyright holder nor the names of
-         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 COPYRIGHT HOLDER
-       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.
-*/
-
-package jdk.internal.dynalink.beans;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.Permissions;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-import java.security.SecureClassLoader;
-
-/**
- * A utility class to check whether a given class is in a package with restricted access e.g. "sun.*". These packages
- * are normally listed in the security property "package.access" for most JRE implementations, although we fortunately
- * don't rely on it but solely on {@link SecurityManager#checkPackageAccess(String)}).
- *
- * This class accomplishes the check in a fashion that works reliably even if Dynalink itself (and all the code on the
- * stack that led to the invocation) has the permission to access the restricted package.
- *
- * If Dynalink has a broad set of privileges (notably, it is loaded from boot or extension class path), then it loads
- * the {@link RestrictedPackageTester} class into a isolated secure class loader that gives it no permissions
- * whatsoever, and uses this completely unprivileged class to subsequently invoke
- * {@link SecurityManager#checkPackageAccess(String)}. This will reliably throw a {@link SecurityException} for every
- * restricted package even if Dynalink and other code on the stack have the requisite {@code "accessClassInPackage.*"}
- * {@link RuntimePermission} privilege.
- *
- * On the other hand, if Dynalink does not have a broad set of privileges normally granted by the boot or extension
- * class path, it will probably lack the privilege to create a new secure class loader into which to load the tester
- * class. In this case, it will invoke {@link SecurityManager#checkPackageAccess(String)} itself with the reasoning that
- * it will also be sufficient to discover whether a package is restricted or not.
- *
- * The rationale for this design is that if Dynalink is running as part of a privileged classpath - boot or extension
- * class path, it will have all privileges, so a security manager's package access check might succeed if all other code
- * on the stack when requesting linking with a particular restricted class is also privileged. A subsequent linking
- * request from less privileged code would then also succeed in requesting methods in privileged package. On the other
- * hand, if Dynalink is privileged, it will be able to delegate the package access check to the unprivileged class and
- * narrow the access based on its result. Finally, if Dynalink itself is unprivileged, it will not be able to load the
- * unprivileged class, but then it will also fail the security manager's package access.
- *
- * With this design, Dynalink effectively restrains itself from giving unauthorized access to restricted packages from
- * classes doing the linking in case it itself has access to those packages. The only way to defeat it would be to
- * selectively give Dynalink some {@code "accessClassInPackage.*"} permissions while denying it the privilege to
- * manipulate class loaders.
- */
-class CheckRestrictedPackageInternal {
-    private static final MethodHandle PACKAGE_ACCESS_CHECK = getPackageAccessCheckMethod();
-    private static final String TESTER_CLASS_NAME = "jdk.internal.dynalink.beans.RestrictedPackageTester";
-
-    /**
-     * Returns true if the specified package has restricted access.
-     * @param pkgName the name of the package to check.
-     * @return true if the specified package has restricted access, false otherwise.
-     * @throws NullPointerException if pkgName is null, or if there is {@link System#getSecurityManager()} returns null
-     * as this method is only expected to be invoked in the presence of a security manager.
-     */
-    static boolean isRestrictedPackageName(String pkgName) {
-        try {
-            if(PACKAGE_ACCESS_CHECK != null) {
-                // If we were able to load our unprivileged tester class, use it to check package access
-                try {
-                    PACKAGE_ACCESS_CHECK.invokeExact(pkgName);
-                } catch(Error|RuntimeException e) {
-                    throw e;
-                } catch(Throwable t) {
-                    throw new RuntimeException(t);
-                }
-            } else {
-                // If we didn't have sufficient permissions to load our unprivileged tester class, we're definitely not
-                // running in a privileged class path, so invoking SecurityManager.checkPackageAccess() directly should
-                // have the same effect as going through an unprivileged tester.
-                System.getSecurityManager().checkPackageAccess(pkgName);
-            }
-            return false;
-        } catch(SecurityException e) {
-            return true;
-        }
-    }
-
-    private static MethodHandle getPackageAccessCheckMethod() {
-        try {
-            return AccessController.doPrivileged(new PrivilegedAction<MethodHandle>() {
-                @Override
-                public MethodHandle run() {
-                    return getPackageAccessCheckMethodInternal();
-                }
-            });
-        } catch(SecurityException e) {
-            // We don't have sufficient privileges to load our tester class into a separate protection domain, so just
-            // return null so isRestrictedPackageName() will default to itself invoking
-            // SecurityManager.checkPackageAccess().
-            return null;
-        }
-    }
-
-    static MethodHandle getPackageAccessCheckMethodInternal() {
-        try {
-            // Can't use MethodHandles.lookup().findStatic() -- even though both this class and the loaded class are in
-            // the same package, findStatic() will throw an IllegalAccessException since they have different class
-            // loaders. That's why we have to use unreflect with a setAccessible(true)...
-            final Method m = getTesterClass().getDeclaredMethod("checkPackageAccess", String.class);
-            m.setAccessible(true);
-            return MethodHandles.lookup().unreflect(m);
-        } catch(IllegalAccessException|NoSuchMethodException e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    private static Class<?> getTesterClass() {
-        final ClassLoader loader = getTesterClassLoader();
-        try {
-            final Class<?> checkerClass = Class.forName(TESTER_CLASS_NAME, true, loader);
-            // Sanity check to ensure we didn't accidentally pick up the class from elsewhere
-            if(checkerClass.getClassLoader() != loader) {
-                throw new AssertionError(TESTER_CLASS_NAME + " was loaded from a different class loader");
-            }
-            return checkerClass;
-        } catch(ClassNotFoundException e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    private static ClassLoader getTesterClassLoader() {
-        // We deliberately override loadClass instead of findClass so that we don't give a chance to finding this
-        // class already loaded anywhere else. Not that there's a big possibility for this, especially since the parent
-        // class loader is the bootstrap class loader, but still...
-        return new SecureClassLoader(null) {
-
-            @Override
-            protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-                if(name.equals(TESTER_CLASS_NAME)) {
-                    final byte[] bytes = getTesterClassBytes();
-                    // Define the class with a protection domain that grants no permissions.
-                    Class<?> clazz = defineClass(name, bytes, 0, bytes.length, new ProtectionDomain(null,
-                            new Permissions()));
-                    if(resolve) {
-                        resolveClass(clazz);
-                    }
-                    return clazz;
-                }
-
-                return super.loadClass(name, resolve);
-            }
-        };
-    }
-
-    static byte[] getTesterClassBytes() {
-        try {
-            final InputStream in = CheckRestrictedPackage.class.getResourceAsStream("RestrictedPackageTester.class");
-            try {
-                final ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
-                for(;;) {
-                    final int b = in.read();
-                    if(b == -1) {
-                        break;
-                    }
-                    out.write(b);
-                }
-                return out.toByteArray();
-            } finally {
-                in.close();
-            }
-        } catch(IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
--- a/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/internal/dynalink/beans/FacetIntrospector.java	Sat Mar 09 21:49:32 2013 +0530
@@ -92,7 +92,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
-import jdk.internal.dynalink.support.Lookup;
 
 /**
  * Base for classes that expose class field and method information to an {@link AbstractJavaLinker}. There are
@@ -161,15 +160,15 @@
 
 
     MethodHandle unreflectGetter(Field field) {
-        return editMethodHandle(Lookup.PUBLIC.unreflectGetter(field));
+        return editMethodHandle(SafeUnreflector.unreflectGetter(field));
     }
 
     MethodHandle unreflectSetter(Field field) {
-        return editMethodHandle(Lookup.PUBLIC.unreflectSetter(field));
+        return editMethodHandle(SafeUnreflector.unreflectSetter(field));
     }
 
     MethodHandle unreflect(Method method) {
-        return editMethodHandle(Lookup.PUBLIC.unreflect(method));
+        return editMethodHandle(SafeUnreflector.unreflect(method));
     }
 
     /**
--- a/src/jdk/internal/dynalink/beans/RestrictedPackageTester.java	Wed Mar 06 22:38:18 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file, and Oracle licenses the original version of this file under the BSD
- * license:
- */
-/*
-   Copyright 2009-2013 Attila Szegedi
-
-   Licensed under both the Apache License, Version 2.0 (the "Apache License")
-   and the BSD License (the "BSD License"), with licensee being free to
-   choose either of the two at their discretion.
-
-   You may not use this file except in compliance with either the Apache
-   License or the BSD License.
-
-   If you choose to use this file in compliance with the Apache License, the
-   following notice applies to you:
-
-       You may obtain a copy of the Apache License at
-
-           http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing, software
-       distributed under the License is distributed on an "AS IS" BASIS,
-       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-       implied. See the License for the specific language governing
-       permissions and limitations under the License.
-
-   If you choose to use this file in compliance with the BSD License, the
-   following notice applies to you:
-
-       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 the copyright holder nor the names of
-         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 COPYRIGHT HOLDER
-       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.
-*/
-
-package jdk.internal.dynalink.beans;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * This class is never referenced directly from code of any other class, but is loaded into a secure class loader that
- * gives it no permissions whatsoever, so it can be used to reliably test whether a given package has restricted access
- * or not. See {@link CheckRestrictedPackageInternal} for details.
- * @author Attila Szegedi
- * @version $Id: $
- */
-class RestrictedPackageTester implements PrivilegedAction<Void> {
-
-    private final String pkgName;
-
-    private RestrictedPackageTester(String pkgName) {
-        this.pkgName = pkgName;
-    }
-
-    static void checkPackageAccess(String pkgName) {
-        AccessController.doPrivileged(new RestrictedPackageTester(pkgName));
-    }
-
-    @Override
-    public Void run() {
-        System.getSecurityManager().checkPackageAccess(pkgName);
-        return null;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/SafeUnreflector.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       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 the copyright holder nor the names of
+         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 COPYRIGHT HOLDER
+       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.
+*/
+
+package jdk.internal.dynalink.beans;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import jdk.internal.dynalink.beans.sandbox.Unreflector;
+
+/**
+ * Provides lookup of unreflected method handles through delegation to an instance of {@link SafeUnreflectorImpl}. If
+ * Dynalink is run as trusted code, the delegate class is loaded into an isolated zero-permissions protection domain,
+ * serving as a firebreak against an accidental privilege escalation downstream.
+ */
+final class SafeUnreflector {
+    private static final String UNREFLECTOR_IMPL_CLASS_NAME = "jdk.internal.dynalink.beans.SafeUnreflectorImpl";
+    private static final Unreflector impl = createImpl();
+
+    private SafeUnreflector() {
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered
+     * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param m the method to unreflect
+     * @return the unreflected method handle.
+     */
+    static MethodHandle unreflect(Method m) {
+        return impl.unreflect(m);
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, converting any encountered
+     * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param f the field for which a getter is unreflected
+     * @return the unreflected field getter handle.
+     */
+    static MethodHandle unreflectGetter(Field f) {
+        return impl.unreflectGetter(f);
+    }
+
+    /**
+     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)}, converting any encountered
+     * {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param f the field for which a setter is unreflected
+     * @return the unreflected field setter handle.
+     */
+    static MethodHandle unreflectSetter(Field f) {
+        return impl.unreflectSetter(f);
+    }
+
+    static MethodHandle unreflectConstructor(Constructor<?> c) {
+        return impl.unreflectConstructor(c);
+    }
+
+    private static Unreflector createImpl() {
+        final Class<?> unreflectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+            @Override
+            public Class<?> run() {
+                return SandboxClassLoader.loadClass(UNREFLECTOR_IMPL_CLASS_NAME);
+            }
+        });
+        try {
+            return (Unreflector)unreflectorImplClass.newInstance();
+        } catch(InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/SafeUnreflectorImpl.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       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 the copyright holder nor the names of
+         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 COPYRIGHT HOLDER
+       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.
+*/
+
+package jdk.internal.dynalink.beans;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import jdk.internal.dynalink.beans.sandbox.Unreflector;
+
+/**
+ * Performs lookup of unreflected method handles by delegating to {@link MethodHandles#lookup()} using itself as the
+ * lookup class. When Dynalink runs as trusted code, this class is loaded into an isolated zero-permissions protection
+ * domain to stop any accidental privilege escalation.
+ */
+final class SafeUnreflectorImpl implements Unreflector {
+
+    SafeUnreflectorImpl() {
+    }
+
+    @Override
+    public MethodHandle unreflect(Method m) {
+        try {
+            return MethodHandles.lookup().unreflect(m);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect method " + m);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    @Override
+    public MethodHandle unreflectGetter(Field f) {
+        try {
+            return MethodHandles.lookup().unreflectGetter(f);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect getter for field " + f);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    @Override
+    public MethodHandle unreflectSetter(Field f) {
+        try {
+            return MethodHandles.lookup().unreflectSetter(f);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect setter for field " + f);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    @Override
+    public MethodHandle unreflectConstructor(Constructor<?> c) {
+        try {
+            return MethodHandles.lookup().unreflectConstructor(c);
+        } catch(IllegalAccessException e) {
+            final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect constructor " + c);
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/SandboxClassLoader.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       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 the copyright holder nor the names of
+         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 COPYRIGHT HOLDER
+       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.
+*/
+
+package jdk.internal.dynalink.beans;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASM4;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.security.SecureRandom;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+/**
+ * A utility class that can load a class with specified name into an isolated zero-permissions protection domain. It can
+ * be used to load classes that perform security-sensitive operations with no privileges at all, therefore ensuring such
+ * operations will only succeed if they would require no permissions, as well as to make sure that if these operations
+ * bind some part of the security execution context to their results, the bound security context is completely
+ * unprivileged. Such measures serve as firebreaks against accidental privilege escalation.
+ */
+final class SandboxClassLoader {
+    private final String className;
+    private final String randomizedClassName;
+
+    private SandboxClassLoader(String className) {
+        this.className = className;
+        final String simpleClassName = className.substring(className.lastIndexOf('.') + 1);
+        this.randomizedClassName = "randomPackage" + Long.toHexString(new SecureRandom().nextLong()) + "." + simpleClassName;
+    }
+
+    /**
+     * Load the named class into a zero-permissions protection domain. Even if the class is already loaded into the
+     * Dynalink's class loader, an independent class is created from the same bytecode, thus the returned class will
+     * never be identical with the one that might already be loaded. The class to be loaded is supposed to be package
+     * private and have no public constructors. This is not a functional requirement, but it is enforced to ensure that
+     * the original class was made adequately inaccessible. The returned class will be public and its constructors will
+     * be changed to public. The only permission given to the returned class will be
+     * {@code accessClassInPackage.jdk.internal.dynalink.beans.sandbox}. That package should be used solely to define
+     * SPI interfaces implemented by the loaded class.
+     * @param className the fully qualified name of the class to load
+     * @return the loaded class, renamed to a random package, made public, its constructors made public, and lacking any
+     * permissions except access to the sandbox package.
+     * @throws SecurityException if the calling code lacks the {@code createClassLoader} runtime permission. This
+     * normally means that Dynalink itself is running as untrusted code, and whatever functionality was meant to be
+     * isolated into an unprivileged class is likely okay to be used directly too.
+     */
+    static Class<?> loadClass(String className) throws SecurityException {
+        return new SandboxClassLoader(className).loadClass();
+    }
+
+    private Class<?> loadClass() throws SecurityException {
+        final ClassLoader loader = createClassLoader();
+        try {
+            final Class<?> clazz = Class.forName(randomizedClassName, true, loader);
+            // Sanity check to ensure we didn't accidentally pick up the class from elsewhere
+            if(clazz.getClassLoader() != loader) {
+                throw new AssertionError(randomizedClassName + " was loaded from a different class loader");
+            }
+            return clazz;
+        } catch(ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private ClassLoader createClassLoader() throws SecurityException {
+        final String lclassName = this.randomizedClassName;
+        // We deliberately override loadClass instead of findClass so that we don't give a chance to finding this
+        // class already loaded anywhere else. We use this class' loader as the parent class loader as the loaded class
+        // needs to be able to access implemented interfaces from the sandbox package.
+        return new SecureClassLoader(getClass().getClassLoader()) {
+            @Override
+            protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+                if(name.equals(lclassName)) {
+                    final byte[] bytes = getClassBytes();
+                    // Define the class with a protection domain that grants (almost) no permissions.
+                    Class<?> clazz = defineClass(name, bytes, 0, bytes.length, createMinimalPermissionsDomain());
+                    if(resolve) {
+                        resolveClass(clazz);
+                    }
+                    return clazz;
+                }
+
+                final int i = name.lastIndexOf('.');
+                if (i != -1) {
+                    final SecurityManager sm = System.getSecurityManager();
+                    if (sm != null) {
+                        sm.checkPackageAccess(name.substring(0, i));
+                    }
+                }
+                return super.loadClass(name, resolve);
+            }
+        };
+    }
+
+    /**
+     * Create a no-permissions protection domain. Except, it's not really a no-permissions protection domain, since we
+     * need to give the protection domain the permission to access the sandbox package where the interop interfaces are
+     * defined.
+     * @return a new (almost) no-permission protection domain.
+     */
+    private static ProtectionDomain createMinimalPermissionsDomain() {
+        final Permissions p = new Permissions();
+        p.add(new RuntimePermission("accessClassInPackage.jdk.internal.dynalink.beans.sandbox"));
+        return new ProtectionDomain(null, p);
+    }
+
+    private byte[] getClassBytes() {
+        try(final InputStream in = getClass().getResourceAsStream("/" + className.replace('.', '/') + ".class")) {
+            final ClassReader cr = new ClassReader(in);
+            final ClassWriter cw = new ClassWriter(cr, 0);
+            cr.accept(new ClassVisitor(ASM4, cw) {
+                @Override
+                public void visit(int version, int access, String name, String signature, String superName,
+                        String[] interfaces) {
+                    // Rename the class to its random name, and make it public (otherwise we won't be able to
+                    // instantiate it). The privileged template class is package-private.
+                    if((access & ACC_PUBLIC) != 0) {
+                        throw new IllegalArgumentException("Class " + className + " must be package-private");
+                    }
+                    super.visit(version, access | ACC_PUBLIC, randomizedClassName.replace('.', '/'),
+                            signature, superName, interfaces);
+                }
+
+                @Override
+                public MethodVisitor visitMethod(int access, String name, String desc, String signature,
+                        String[] exceptions) {
+                    // Make the constructor(s) public (otherwise we won't be able to instantiate the class). The
+                    // privileged template's constructor(s) should not be public.
+                    final boolean isCtor = "<init>".equals(name);
+                    if(isCtor && ((access & ACC_PUBLIC) != 0)) {
+                        throw new IllegalArgumentException("Class " + className + " must have no public constructors");
+                    }
+                    return super.visitMethod(isCtor ? (access | ACC_PUBLIC) : access, name, desc, signature,
+                            exceptions);
+                }
+            }, 0);
+            return cw.toByteArray();
+        } catch(IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- a/src/jdk/internal/dynalink/beans/StaticClassLinker.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/internal/dynalink/beans/StaticClassLinker.java	Sat Mar 09 21:49:32 2013 +0530
@@ -138,7 +138,7 @@
             final Constructor<?>[] ctrs = clazz.getConstructors();
             final List<MethodHandle> mhs = new ArrayList<>(ctrs.length);
             for(int i = 0; i < ctrs.length; ++i) {
-                mhs.add(drop(Lookup.PUBLIC.unreflectConstructor(ctrs[i])));
+                mhs.add(drop(SafeUnreflector.unreflectConstructor(ctrs[i])));
             }
             return createDynamicMethod(mhs, clazz, "<init>");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/internal/dynalink/beans/sandbox/Unreflector.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+   Copyright 2009-2013 Attila Szegedi
+
+   Licensed under both the Apache License, Version 2.0 (the "Apache License")
+   and the BSD License (the "BSD License"), with licensee being free to
+   choose either of the two at their discretion.
+
+   You may not use this file except in compliance with either the Apache
+   License or the BSD License.
+
+   If you choose to use this file in compliance with the Apache License, the
+   following notice applies to you:
+
+       You may obtain a copy of the Apache License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+       implied. See the License for the specific language governing
+       permissions and limitations under the License.
+
+   If you choose to use this file in compliance with the BSD License, the
+   following notice applies to you:
+
+       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 the copyright holder nor the names of
+         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 COPYRIGHT HOLDER
+       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.
+*/
+
+package jdk.internal.dynalink.beans.sandbox;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Interface for creating unreflected method handles. This class is public for implementation purposes and is not part
+ * of any supported API.
+ */
+public interface Unreflector {
+    /**
+     * Performs similarly to {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)} for some lookup object,
+     * also converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param m the method to unreflect
+     * @return the unreflected method handle.
+     */
+    public MethodHandle unreflect(Method m);
+
+    /**
+     * Performs similarly to {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)} for some lookup
+     * object, also converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param f the field for which a getter is unreflected
+     * @return the unreflected field getter handle.
+     */
+    public MethodHandle unreflectGetter(Field f);
+
+    /**
+     * Performs similarly to {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)} for some lookup
+     * object, also converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param f the field for which a setter is unreflected
+     * @return the unreflected field setter handle.
+     */
+    public MethodHandle unreflectSetter(Field f);
+
+    /**
+     * Performs similarly to {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)} for some
+     * lookup object, also converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
+     *
+     * @param c the constructor to unreflect
+     * @return the unreflected constructor handle.
+     */
+    public MethodHandle unreflectConstructor(Constructor<?> c);
+
+}
--- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.codegen;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/codegen/FunctionSignature.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/codegen/FunctionSignature.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.codegen;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodType;
 import java.util.ArrayList;
--- a/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Sat Mar 09 21:49:32 2013 +0530
@@ -34,7 +34,7 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.MAP;
 import static jdk.nashorn.internal.codegen.CompilerConstants.className;
 import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java	Sat Mar 09 21:49:32 2013 +0530
@@ -28,7 +28,7 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
 import static jdk.nashorn.internal.codegen.types.Type.BOOLEAN;
 import static jdk.nashorn.internal.codegen.types.Type.INT;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.CallSite;
 import java.lang.invoke.MethodHandle;
@@ -43,8 +43,8 @@
 import jdk.nashorn.internal.ir.RuntimeNode.Request;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
-import jdk.nashorn.internal.runtime.linker.Lookup;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 
 /**
  * Optimistic call site that assumes its Object arguments to be of a boxed type.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/lookup/Lookup.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,212 @@
+/*
+ * 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.lookup;
+
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * MethodHandle Lookup management for Nashorn.
+ */
+public final class Lookup {
+
+    /**
+     * A global singleton that points to the {@link MethodHandleFunctionality}. This is basically
+     * a collection of wrappers to the standard methods in {@link MethodHandle}, {@link MethodHandles} and
+     * {@link java.lang.invoke.MethodHandles.Lookup}, but instrumentation and debugging purposes we need
+     * intercept points.
+     * <p>
+     * All method handle operations in Nashorn should go through this field, not directly to the classes
+     * in {@code java.lang.invoke}
+     */
+    public static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
+
+    /** Method handle to the empty getter */
+    public static final MethodHandle EMPTY_GETTER = findOwnMH("emptyGetter", Object.class, Object.class);
+
+    /** Method handle to the empty setter */
+    public static final MethodHandle EMPTY_SETTER = findOwnMH("emptySetter", void.class, Object.class, Object.class);
+
+    /** Method handle to a getter that only throws type error */
+    public static final MethodHandle TYPE_ERROR_THROWER_GETTER = findOwnMH("typeErrorThrowerGetter", Object.class, Object.class);
+
+    /** Method handle to a setter that only throws type error */
+    public static final MethodHandle TYPE_ERROR_THROWER_SETTER = findOwnMH("typeErrorThrowerSetter", void.class, Object.class, Object.class);
+
+    /** Method handle to the most generic of getters, the one that returns an Object */
+    public static final MethodType GET_OBJECT_TYPE = MH.type(Object.class, Object.class);
+
+    /** Method handle to the most generic of setters, the one that takes an Object */
+    public static final MethodType SET_OBJECT_TYPE = MH.type(void.class, Object.class, Object.class);
+
+    private Lookup() {
+    }
+
+    /**
+     * Empty getter implementation. Nop
+     * @param self self reference
+     * @return undefined
+     */
+    public static Object emptyGetter(final Object self) {
+        return UNDEFINED;
+    }
+
+    /**
+     * Empty setter implementation. Nop
+     * @param self  self reference
+     * @param value value (ignored)
+     */
+    public static void emptySetter(final Object self, final Object value) {
+        // do nothing!!
+    }
+
+    /**
+     * Return a method handle to the empty getter, with a different
+     * return type value. It will still be undefined cast to whatever
+     * return value property was specified
+     *
+     * @param type return value type
+     *
+     * @return undefined as return value type
+     */
+    public static MethodHandle emptyGetter(final Class<?> type) {
+        return filterReturnType(EMPTY_GETTER, type);
+    }
+
+    /**
+     * Getter function that always throws type error
+     *
+     * @param self  self reference
+     * @return undefined (but throws error before return point)
+     */
+    public static Object typeErrorThrowerGetter(final Object self) {
+        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
+    }
+
+    /**
+     * Getter function that always throws type error
+     *
+     * @param self  self reference
+     * @param value (ignored)
+     */
+    public static void typeErrorThrowerSetter(final Object self, final Object value) {
+        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
+    }
+
+    /**
+     * Create a new {@link Property}
+     *
+     * @param map             property map
+     * @param key             property key
+     * @param flags           property flags
+     * @param propertyGetter  getter for property if available, null otherwise
+     * @param propertySetter  setter for property if available, null otherwise
+     *
+     * @return new property map, representing {@code PropertyMap} with the new property added to it
+     */
+    @SuppressWarnings("fallthrough")
+    public static PropertyMap newProperty(final PropertyMap map, final String key, final int flags, final MethodHandle propertyGetter, final MethodHandle propertySetter) {
+        MethodHandle getter = propertyGetter;
+        MethodHandle setter = propertySetter;
+
+        // TODO: this is temporary code. This code exists to support reflective
+        // field reader/writer handles generated by "unreflect" lookup.
+
+        switch (getter.type().parameterCount()) {
+        case 0:
+            // A static field reader, so drop the 'self' argument.
+            getter = MH.dropArguments(getter, 0, Object.class);
+            if (setter != null) {
+                setter = MH.dropArguments(setter, 0, Object.class);
+            }
+        // fall through
+        case 1:
+            // standard getter that accepts 'self'.
+            break;
+        default:
+            // Huh!! something wrong..
+            throw new IllegalArgumentException("getter/setter has wrong arguments");
+        }
+
+        return map.newProperty(key, flags, -1, getter, setter);
+    }
+
+    /**
+     * This method filters primitive return types using JavaScript semantics. For example,
+     * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
+     * If you are returning values to JavaScript that have to be of a specific type, this is
+     * the correct return value filter to use, as the explicitCastArguments just uses the
+     * Java boxing equivalents
+     *
+     * @param mh   method handle for which to filter return value
+     * @param type new return type
+     * @return method handle for appropriate return type conversion
+     */
+    public static MethodHandle filterReturnType(final MethodHandle mh, final Class<?> type) {
+        final Class<?> retType = mh.type().returnType();
+
+        if (retType == int.class) {
+            //fallthru
+        } else if (retType == long.class) {
+            //fallthru
+        } else if (retType == double.class) {
+            if (type == int.class) {
+                return MH.filterReturnValue(mh, JSType.TO_INT32_D.methodHandle());
+            } else if (type == long.class) {
+                return MH.filterReturnValue(mh, JSType.TO_UINT32_D.methodHandle());
+            }
+            //fallthru
+        } else if (!retType.isPrimitive()) {
+            if (type == int.class) {
+                return MH.filterReturnValue(mh, JSType.TO_INT32.methodHandle());
+            } else if (type == long.class) {
+                return MH.filterReturnValue(mh, JSType.TO_UINT32.methodHandle());
+            } else if (type == double.class) {
+                return MH.filterReturnValue(mh, JSType.TO_NUMBER.methodHandle());
+            } else if (!type.isPrimitive()) {
+                return mh;
+            }
+
+            assert false : "unsupported Lookup.filterReturnType type " + retType + " -> " + type;
+        }
+
+        //use a standard cast - we don't need to check JavaScript special cases
+        return MH.explicitCastArguments(mh, mh.type().changeReturnType(type));
+    }
+
+    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+        return MH.findStatic(MethodHandles.lookup(), Lookup.class, name, MH.type(rtype, types));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,646 @@
+/*
+ * 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.lookup;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.Debug;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.options.Options;
+
+/**
+ * This class is abstraction for all method handle, switchpoint and method type
+ * operations. This enables the functionality interface to be subclassed and
+ * intrumensted, as it has been proven vital to keep the number of method
+ * handles in the system down.
+ *
+ * All operations of the above type should go through this class, and not
+ * directly into java.lang.invoke
+ *
+ */
+public final class MethodHandleFactory {
+
+    private static final MethodHandles.Lookup PUBLIC_LOOKUP = MethodHandles.publicLookup();
+    private static final MethodHandles.Lookup LOOKUP        = MethodHandles.lookup();
+
+    private static final Level TRACE_LEVEL = Level.INFO;
+
+    private MethodHandleFactory() {
+    }
+
+    /**
+     * Runtime exception that collects every reason that a method handle lookup operation can go wrong
+     */
+    @SuppressWarnings("serial")
+    public static class LookupException extends RuntimeException {
+        /**
+         * Constructor
+         * @param e causing exception
+         */
+        public LookupException(final Exception e) {
+            super(e);
+        }
+    }
+
+    /**
+     * Helper function that takes a class or an object with a toString override
+     * and shortens it to notation after last dot. This is used to facilitiate
+     * pretty printouts in various debug loggers - internal only
+     *
+     * @param obj class or object
+     *
+     * @return pretty version of object as string
+     */
+    public static String stripName(final Object obj) {
+        if (obj == null) {
+            return "null";
+        }
+
+        if (obj instanceof Class) {
+            return ((Class<?>)obj).getSimpleName();
+        }
+        return obj.toString();
+    }
+
+    private static final MethodHandleFunctionality STANDARD = new StandardMethodHandleFunctionality();
+    private static final MethodHandleFunctionality FUNC;
+
+    private static final String DEBUG_PROPERTY = "nashorn.methodhandles.debug";
+    private static final DebugLogger LOG = new DebugLogger("methodhandles", DEBUG_PROPERTY);
+
+    static {
+        if (LOG.isEnabled() || Options.getBooleanProperty(DEBUG_PROPERTY)) {
+            if (Options.getStringProperty(DEBUG_PROPERTY, "").equals("create")) {
+                FUNC = new TraceCreateMethodHandleFunctionality();
+            } else {
+                FUNC = new TraceMethodHandleFunctionality();
+            }
+        } else {
+            FUNC  = STANDARD;
+        }
+    }
+
+    private static final boolean PRINT_STACKTRACE = Options.getBooleanProperty("nashorn.methodhandles.debug.stacktrace");
+
+
+    /**
+     * Return the method handle functionality used for all method handle operations
+     * @return a method handle functionality implementation
+     */
+    public static MethodHandleFunctionality getFunctionality() {
+        return FUNC;
+    }
+
+    private static final MethodHandle TRACE        = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs",   MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
+    private static final MethodHandle TRACE_RETURN = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
+
+    /**
+     * Tracer that is applied before a value is returned from the traced function. It will output the return
+     * value and its class
+     *
+     * @param value return value for filter
+     * @return return value unmodified
+     */
+    static Object traceReturn(final DebugLogger logger, final Object value) {
+        final String str = "\treturn: " + stripName(value) + " [type=" + (value == null ? "null" : stripName(value.getClass()) + ']');
+        logger.log(str, TRACE_LEVEL);
+        return value;
+    }
+
+    /**
+     * Tracer that is applied before a function is called, printing the arguments
+     *
+     * @param tag  tag to start the debug printout string
+     * @param paramStart param index to start outputting from
+     * @param args arguments to the function
+     */
+    static void traceArgs(final DebugLogger logger, final String tag, final int paramStart, final Object... args) {
+        final StringBuilder sb = new StringBuilder();
+
+        sb.append(tag);
+
+        for (int i = paramStart; i < args.length; i++) {
+            if (i == paramStart) {
+                sb.append(" => args: ");
+            }
+
+            sb.append('\'').
+                append(stripName(argString(args[i]))).
+                append('\'').
+                append(' ').
+                append('[').
+                append("type=").
+                append(args[i] == null ? "null" : stripName(args[i].getClass())).
+                append(']');
+
+            if (i + 1 < args.length) {
+                sb.append(", ");
+            }
+        }
+
+        assert logger != null;
+        logger.log(sb.toString(), TRACE_LEVEL);
+        stacktrace(logger);
+    }
+
+    private static void stacktrace(final DebugLogger logger) {
+        if (!PRINT_STACKTRACE) {
+            return;
+        }
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final PrintStream ps = new PrintStream(baos);
+        new Throwable().printStackTrace(ps);
+        logger.log(baos.toString(), TRACE_LEVEL);
+    }
+
+    private static String argString(final Object arg) {
+        if (arg == null) {
+            return "null";
+        }
+
+        if (arg.getClass().isArray()) {
+            final List<Object> list = new ArrayList<>();
+            for (final Object elem : (Object[])arg) {
+                list.add('\'' + argString(elem) + '\'');
+            }
+
+            return list.toString();
+        }
+
+        if (arg instanceof ScriptObject) {
+            return arg.toString() +
+                " (map=" + Debug.id((((ScriptObject)arg).getMap())) +
+                ")";
+        }
+
+        return arg.toString();
+    }
+
+    /**
+     * Add a debug printout to a method handle, tracing parameters and return values
+     *
+     * @param logger a specific logger to which to write the output
+     * @param mh  method handle to trace
+     * @param tag start of trace message
+     * @return traced method handle
+     */
+    public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final Object tag) {
+        return addDebugPrintout(logger, mh, 0, true, tag);
+    }
+
+
+    /**
+     * Add a debug printout to a method handle, tracing parameters and return values
+     *
+     * @param logger a specific logger to which to write the output
+     * @param mh  method handle to trace
+     * @param paramStart first param to print/trace
+     * @param printReturnValue should we print/trace return value if available?
+     * @param tag start of trace message
+     * @return  traced method handle
+     */
+    public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
+        final MethodType type = mh.type();
+
+        if (logger != null && logger.levelAbove(TRACE_LEVEL)) {
+            return mh;
+        }
+
+        assert logger != null;
+        assert TRACE != null;
+
+        MethodHandle trace = MethodHandles.insertArguments(TRACE, 0, logger, tag, paramStart);
+
+        trace = MethodHandles.foldArguments(
+                mh,
+                trace.asCollector(
+                    Object[].class,
+                    type.parameterCount()).
+                asType(type.changeReturnType(void.class)));
+
+        final Class<?> retType = type.returnType();
+        if (retType != void.class && printReturnValue) {
+            final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
+            trace = MethodHandles.filterReturnValue(trace,
+                    traceReturn.asType(
+                        traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
+        }
+
+        return trace;
+    }
+
+    /**
+     * The standard class that marshalls all method handle operations to the java.lang.invoke
+     * package. This exists only so that it can be subclassed and method handles created from
+     * Nashorn made possible to instrument.
+     *
+     * All Nashorn classes should use the MethodHandleFactory for their method handle operations
+     */
+    private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality {
+
+        @Override
+        public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
+            return MethodHandles.filterArguments(target, pos, filters);
+        }
+
+        @Override
+        public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
+            return MethodHandles.filterReturnValue(target, filter);
+        }
+
+        @Override
+        public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
+            return MethodHandles.guardWithTest(test, target, fallback);
+        }
+
+        @Override
+        public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
+            return MethodHandles.insertArguments(target, pos, values);
+        }
+
+        @Override
+        public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
+            return MethodHandles.dropArguments(target, pos, valueTypes);
+        }
+
+        @Override
+        public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes) {
+            return MethodHandles.dropArguments(target, pos, valueTypes);
+        }
+
+        @Override
+        public MethodHandle asType(final MethodHandle handle, final MethodType type) {
+            return handle.asType(type);
+        }
+
+        @Override
+        public MethodHandle bindTo(final MethodHandle handle, final Object x) {
+            return handle.bindTo(x);
+        }
+
+        @Override
+        public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
+            return MethodHandles.foldArguments(target, combiner);
+        }
+
+        @Override
+        public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
+            return MethodHandles.explicitCastArguments(target, type);
+        }
+
+        @Override
+        public MethodHandle arrayElementGetter(final Class<?> type) {
+            return MethodHandles.arrayElementGetter(type);
+        }
+
+        @Override
+        public MethodHandle arrayElementSetter(final Class<?> type) {
+            return MethodHandles.arrayElementSetter(type);
+        }
+
+        @Override
+        public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
+            return MethodHandles.throwException(returnType, exType);
+        }
+
+        @Override
+        public MethodHandle constant(final Class<?> type, final Object value) {
+            return MethodHandles.constant(type, value);
+        }
+
+        @Override
+        public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+            return handle.asCollector(arrayType, arrayLength);
+        }
+
+        @Override
+        public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+            return handle.asSpreader(arrayType, arrayLength);
+        }
+
+        @Override
+        public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            try {
+                return explicitLookup.findGetter(clazz, name, type);
+            } catch (final NoSuchFieldException | IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+        @Override
+        public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            try {
+                return explicitLookup.findStaticGetter(clazz, name, type);
+            } catch (final NoSuchFieldException | IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+
+        @Override
+        public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            try {
+                return explicitLookup.findSetter(clazz, name, type);
+            } catch (final NoSuchFieldException | IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+        @Override
+        public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            try {
+                return explicitLookup.findStaticSetter(clazz, name, type);
+            } catch (final NoSuchFieldException | IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+        @Override
+        public MethodHandle find(final Method method) {
+            try {
+                return PUBLIC_LOOKUP.unreflect(method);
+            } catch (final IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+        @Override
+        public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+            try {
+                return explicitLookup.findStatic(clazz, name, type);
+            } catch (final NoSuchMethodException | IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+        @Override
+        public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+            try {
+                return explicitLookup.findVirtual(clazz, name, type);
+            } catch (final NoSuchMethodException | IllegalAccessException e) {
+                throw new LookupException(e);
+            }
+        }
+
+        @Override
+        public SwitchPoint createSwitchPoint() {
+            return new SwitchPoint();
+        }
+
+        @Override
+        public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
+            return sp.guardWithTest(before, after);
+        }
+
+        @Override
+        public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
+            return MethodType.methodType(returnType, paramTypes);
+        }
+
+    }
+
+    /**
+     * Class used for instrumenting and debugging Nashorn generated method handles
+     */
+    private static class TraceMethodHandleFunctionality extends StandardMethodHandleFunctionality {
+
+        protected static String describe(final Object... data) {
+            final StringBuilder sb = new StringBuilder();
+
+            for (int i = 0; i < data.length; i++) {
+                final Object d = data[i];
+                if (d == null) {
+                    sb.append("<null> ");
+                } else if (d instanceof String || d instanceof ConsString) {
+                    sb.append(d.toString());
+                    sb.append(' ');
+                } else if (d.getClass().isArray()) {
+                    sb.append("[ ");
+                    for (final Object da : (Object[])d) {
+                        sb.append(describe(new Object[]{ da })).append(' ');
+                    }
+                    sb.append("] ");
+                } else {
+                    sb.append(d)
+                        .append('{')
+                        .append(Integer.toHexString(System.identityHashCode(d)))
+                        .append('}');
+                }
+
+                if (i + 1 < data.length) {
+                    sb.append(", ");
+                }
+            }
+
+            return sb.toString();
+        }
+
+        public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
+            return addDebugPrintout(LOG, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
+        }
+
+        @Override
+        public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
+            final MethodHandle mh = super.filterArguments(target, pos, filters);
+            return debug(mh, "filterArguments", target, pos, filters);
+        }
+
+        @Override
+        public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
+            final MethodHandle mh = super.filterReturnValue(target, filter);
+            return debug(mh, "filterReturnValue", target, filter);
+        }
+
+        @Override
+        public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
+            final MethodHandle mh = super.guardWithTest(test, target, fallback);
+            return debug(mh, "guardWithTest", test, target, fallback);
+        }
+
+        @Override
+        public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
+            final MethodHandle mh = super.insertArguments(target, pos, values);
+            return debug(mh, "insertArguments", target, pos, values);
+        }
+
+        @Override
+        public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
+            final MethodHandle mh = super.dropArguments(target, pos, values);
+            return debug(mh, "dropArguments", target, pos, values);
+        }
+
+        @Override
+        public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
+            final MethodHandle mh = super.dropArguments(target, pos, values);
+            return debug(mh, "dropArguments", target, pos, values);
+        }
+
+        @Override
+        public MethodHandle asType(final MethodHandle handle, final MethodType type) {
+            final MethodHandle mh = super.asType(handle, type);
+            return debug(mh, "asType", handle, type);
+        }
+
+        @Override
+        public MethodHandle bindTo(final MethodHandle handle, final Object x) {
+            final MethodHandle mh = super.bindTo(handle, x);
+            return debug(mh, "bindTo", handle, x);
+        }
+
+        @Override
+        public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
+            final MethodHandle mh = super.foldArguments(target, combiner);
+            return debug(mh, "foldArguments", target, combiner);
+        }
+
+        @Override
+        public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
+            final MethodHandle mh = super.explicitCastArguments(target, type);
+            return debug(mh, "explicitCastArguments", target, type);
+        }
+
+        @Override
+        public MethodHandle arrayElementGetter(final Class<?> type) {
+            final MethodHandle mh = super.arrayElementGetter(type);
+            return debug(mh, "arrayElementGetter", type);
+        }
+
+        @Override
+        public MethodHandle arrayElementSetter(final Class<?> type) {
+            final MethodHandle mh = super.arrayElementSetter(type);
+            return debug(mh, "arrayElementSetter", type);
+        }
+
+        @Override
+        public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
+            final MethodHandle mh = super.throwException(returnType, exType);
+            return debug(mh, "throwException", returnType, exType);
+        }
+
+        @Override
+        public MethodHandle constant(final Class<?> type, final Object value) {
+            final MethodHandle mh = super.constant(type, value);
+            return debug(mh, "constant", type, value);
+        }
+
+        @Override
+        public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+            final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
+            return debug(mh, "asCollector", handle, arrayType, arrayLength);
+        }
+
+        @Override
+        public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
+            final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
+            return debug(mh, "asSpreader", handle, arrayType, arrayLength);
+        }
+
+        @Override
+        public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            final MethodHandle mh = super.getter(explicitLookup, clazz, name, type);
+            return debug(mh, "getter", explicitLookup, clazz, name, type);
+        }
+
+        @Override
+        public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            final MethodHandle mh = super.staticGetter(explicitLookup, clazz, name, type);
+            return debug(mh, "static getter", explicitLookup, clazz, name, type);
+        }
+
+        @Override
+        public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            final MethodHandle mh = super.setter(explicitLookup, clazz, name, type);
+            return debug(mh, "setter", explicitLookup, clazz, name, type);
+        }
+
+        @Override
+        public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
+            final MethodHandle mh = super.staticSetter(explicitLookup, clazz, name, type);
+            return debug(mh, "static setter", explicitLookup, clazz, name, type);
+        }
+
+        @Override
+        public MethodHandle find(final Method method) {
+            final MethodHandle mh = super.find(method);
+            return debug(mh, "find", method);
+        }
+
+        @Override
+        public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+            final MethodHandle mh = super.findStatic(explicitLookup, clazz, name, type);
+            return debug(mh, "findStatic", explicitLookup, clazz, name, type);
+        }
+
+        @Override
+        public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
+            final MethodHandle mh = super.findVirtual(explicitLookup, clazz, name, type);
+            return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
+        }
+
+        @Override
+        public SwitchPoint createSwitchPoint() {
+            final SwitchPoint sp = super.createSwitchPoint();
+            LOG.log("createSwitchPoint " + sp, TRACE_LEVEL);
+            return sp;
+        }
+
+        @Override
+        public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
+            final MethodHandle mh = super.guardWithTest(sp, before, after);
+            return debug(mh, "guardWithTest", sp, before, after);
+        }
+
+        @Override
+        public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
+            final MethodType mt = super.type(returnType, paramTypes);
+            LOG.log("methodType " + returnType + ' ' + Arrays.toString(paramTypes) + ' ' + mt, TRACE_LEVEL);
+            return mt;
+        }
+    }
+
+    /**
+     * Class used for debugging Nashorn generated method handles
+     */
+    private static class TraceCreateMethodHandleFunctionality extends TraceMethodHandleFunctionality {
+        @Override
+        public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
+            LOG.log(str + ' ' + describe(args), TRACE_LEVEL);
+            stacktrace(LOG);
+            return master;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,317 @@
+/*
+ * 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.lookup;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * Wrapper for all method handle related functions used in Nashorn. This interface only exists
+ * so that instrumentation can be added to all method handle operations.
+ */
+
+public interface MethodHandleFunctionality {
+    /**
+     * Wrapper for {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}
+     *
+     * @param target  target method handle
+     * @param pos     start argument index
+     * @param filters filters
+     *
+     * @return filtered handle
+     */
+    public MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters);
+
+    /**
+     * Wrapper for {@link MethodHandles#filterReturnValue(MethodHandle, MethodHandle)}
+     *
+     * @param target  target method handle
+     * @param filter  filter
+     *
+     * @return filtered handle
+     */
+    public MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter);
+
+    /**
+     * Wrapper for {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}
+     *
+     * @param test     test method handle
+     * @param target   target method handle when test is true
+     * @param fallback fallback method handle when test is false
+     *
+     * @return guarded handles
+     */
+    public MethodHandle guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback);
+
+    /**
+     * Wrapper for {@link MethodHandles#insertArguments(MethodHandle, int, Object...)}
+     *
+     * @param target target method handle
+     * @param pos    start argument index
+     * @param values values to insert
+     *
+     * @return handle with bound arguments
+     */
+    public MethodHandle insertArguments(MethodHandle target, int pos, Object... values);
+
+    /**
+     * Wrapper for {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}
+     *
+     * @param target     target method handle
+     * @param pos        start argument index
+     * @param valueTypes valueTypes of arguments to drop
+     *
+     * @return handle with dropped arguments
+     */
+    public MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes);
+
+    /**
+     * Wrapper for {@link MethodHandles#dropArguments(MethodHandle, int, List)}
+     *
+     * @param target     target method handle
+     * @param pos        start argument index
+     * @param valueTypes valueTypes of arguments to drop
+     *
+     * @return handle with dropped arguments
+     */
+    public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes);
+
+    /**
+     * Wrapper for {@link MethodHandles#foldArguments(MethodHandle, MethodHandle)}
+     *
+     * @param target   target method handle
+     * @param combiner combiner to apply for fold
+     *
+     * @return folded method handle
+     */
+    public MethodHandle foldArguments(MethodHandle target, MethodHandle combiner);
+
+    /**
+     * Wrapper for {@link MethodHandles#explicitCastArguments(MethodHandle, MethodType)}
+     *
+     * @param target  target method handle
+     * @param type    type to cast to
+     *
+     * @return modified method handle
+     */
+    public MethodHandle explicitCastArguments(MethodHandle target, MethodType type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles#arrayElementGetter(Class)}
+     *
+     * @param arrayClass class for array
+     *
+     * @return array element getter
+     */
+    public MethodHandle arrayElementGetter(Class<?> arrayClass);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles#arrayElementSetter(Class)}
+     *
+     * @param arrayClass class for array
+     *
+     * @return array element setter
+     */
+    public MethodHandle arrayElementSetter(Class<?> arrayClass);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles#throwException(Class, Class)}
+     *
+     * @param returnType ignored, but method signature will use it
+     * @param exType     exception type that will be thrown
+     *
+     * @return exception thrower method handle
+     */
+    public MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles#constant(Class, Object)}
+     *
+     * @param type  type of constant
+     * @param value constant value
+     *
+     * @return method handle that returns said constant
+     */
+    public MethodHandle constant(Class<?> type, Object value);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandle#asType(MethodType)}
+     *
+     * @param handle  method handle for type conversion
+     * @param type    type to convert to
+     *
+     * @return method handle with given type conversion applied
+     */
+    public MethodHandle asType(MethodHandle handle, MethodType type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandle#asCollector(Class, int)}
+     *
+     * @param handle      handle to convert
+     * @param arrayType   array type for collector array
+     * @param arrayLength length of collector array
+     *
+     * @return method handle with collector
+     */
+    public MethodHandle asCollector(MethodHandle handle, Class<?> arrayType, int arrayLength);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandle#asSpreader(Class, int)}
+     *
+     * @param handle      handle to convert
+     * @param arrayType   array type for spread
+     * @param arrayLength length of spreader
+     *
+     * @return method handle as spreader
+     */
+    public MethodHandle asSpreader(MethodHandle handle, Class<?> arrayType, int arrayLength);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandle#bindTo(Object)}
+     *
+     * @param handle a handle to which to bind a receiver
+     * @param x      the receiver
+     *
+     * @return the bound handle
+     */
+    public MethodHandle bindTo(MethodHandle handle, Object x);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}
+      *
+     * @param explicitLookup explicit lookup to be used
+     * @param clazz          class to look in
+     * @param name           name of field
+     * @param type           type of field
+     *
+     * @return getter method handle for virtual field
+     */
+    public MethodHandle getter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter(Class, String, Class)}
+      *
+     * @param explicitLookup explicit lookup to be used
+     * @param clazz          class to look in
+     * @param name           name of field
+     * @param type           type of field
+     *
+     * @return getter method handle for static field
+     */
+    public MethodHandle staticGetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSetter(Class, String, Class)}
+      *
+     * @param explicitLookup explicit lookup to be used
+     * @param clazz          class to look in
+     * @param name           name of field
+     * @param type           type of field
+     *
+     * @return setter method handle for virtual field
+     */
+    public MethodHandle setter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter(Class, String, Class)}
+      *
+     * @param explicitLookup explicit lookup to be used
+     * @param clazz          class to look in
+     * @param name           name of field
+     * @param type           type of field
+     *
+     * @return setter method handle for static field
+     */
+    public MethodHandle staticSetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}
+     *
+     * Unreflect a method as a method handle
+     *
+     * @param method method to unreflect
+     * @return unreflected method as method handle
+     */
+    public MethodHandle find(Method method);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStatic(Class, String, MethodType)}
+     *
+     * @param explicitLookup explicit lookup to be used
+     * @param clazz          class to look in
+     * @param name           name of method
+     * @param type           method type
+     *
+     * @return method handle for static method
+     */
+    public MethodHandle findStatic(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
+
+    /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findVirtual(Class, String, MethodType)}
+     *
+     * @param explicitLookup explicit lookup to be used
+     * @param clazz          class to look in
+     * @param name           name of method
+     * @param type           method type
+     *
+     * @return method handle for virtual method
+     */
+    public MethodHandle findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
+
+    /**
+     * Wrapper for SwitchPoint creation. Just like {@code new SwitchPoint()} but potentially
+     * tracked
+     *
+     * @return new switch point
+     */
+    public SwitchPoint createSwitchPoint();
+
+    /**
+     * Wrapper for {@link SwitchPoint#guardWithTest(MethodHandle, MethodHandle)}
+     *
+     * @param sp     switch point
+     * @param before method handle when switchpoint is valid
+     * @param after  method handle when switchpoint is invalidated
+     *
+     * @return guarded method handle
+     */
+    public MethodHandle guardWithTest(SwitchPoint sp, MethodHandle before, MethodHandle after);
+
+    /**
+     * Wrapper for {@link MethodType#methodType(Class, Class...)}
+     *
+     * @param returnType  return type for method type
+     * @param paramTypes  parameter types for method type
+     *
+     * @return the method type
+     */
+    public MethodType type(Class<?> returnType, Class<?>... paramTypes);
+}
+
--- a/src/jdk/nashorn/internal/objects/Global.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/Global.java	Sat Mar 09 21:49:32 2013 +0530
@@ -27,7 +27,7 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.io.IOException;
 import java.io.PrintWriter;
--- a/src/jdk/nashorn/internal/objects/NativeArguments.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeArguments.java	Sat Mar 09 21:49:32 2013 +0530
@@ -28,7 +28,7 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -42,7 +42,7 @@
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 
 /**
  * ECMA 10.6 Arguments Object.
--- a/src/jdk/nashorn/internal/objects/NativeBoolean.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeBoolean.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -39,7 +39,7 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
 
 /**
--- a/src/jdk/nashorn/internal/objects/NativeError.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeError.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Sat Mar 09 21:49:32 2013 +0530
@@ -27,7 +27,7 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -46,8 +46,8 @@
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
-import jdk.nashorn.internal.runtime.linker.Lookup;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 
 /**
  * This class is the implementation of the Nashorn-specific global object named {@code JSAdapter}. It can be
--- a/src/jdk/nashorn/internal/objects/NativeNumber.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeNumber.java	Sat Mar 09 21:49:32 2013 +0530
@@ -30,7 +30,7 @@
 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsLong;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -47,7 +47,7 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
 
 /**
--- a/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeStrictArguments.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -36,7 +36,7 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 
 /**
  * ECMA 10.6 Arguments Object.
--- a/src/jdk/nashorn/internal/objects/NativeString.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeString.java	Sat Mar 09 21:49:32 2013 +0530
@@ -29,7 +29,7 @@
 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -55,7 +55,7 @@
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
 
--- a/src/jdk/nashorn/internal/objects/PrototypeObject.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/PrototypeObject.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -34,7 +34,7 @@
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 
 /**
  * Instances of this class serve as "prototype" object for script functions.
--- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Sat Mar 09 21:49:32 2013 +0530
@@ -34,7 +34,7 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 
 /**
  * Concrete implementation of ScriptFunction. This sets correct map for the
--- a/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java	Sat Mar 09 21:49:32 2013 +0530
@@ -1,6 +1,6 @@
 package jdk.nashorn.internal.objects;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Sat Mar 09 21:49:32 2013 +0530
@@ -36,16 +36,16 @@
 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorType;
 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorTypeIndex;
 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getNumberOfAccessorTypes;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
-import static jdk.nashorn.internal.runtime.linker.MethodHandleFactory.stripName;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+import static jdk.nashorn.internal.lookup.MethodHandleFactory.stripName;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 import jdk.nashorn.internal.codegen.types.Type;
-import jdk.nashorn.internal.runtime.linker.Lookup;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 
 /**
  * An AccessorProperty is the most generic property type. An AccessorProperty is
--- a/src/jdk/nashorn/internal/runtime/Context.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/Context.java	Sat Mar 09 21:49:32 2013 +0530
@@ -29,7 +29,7 @@
 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.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.io.File;
 import java.io.IOException;
--- a/src/jdk/nashorn/internal/runtime/FindProperty.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/FindProperty.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
--- a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.runtime;
 
 import static jdk.nashorn.internal.runtime.JSType.digit;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Sat Mar 09 21:49:32 2013 +0530
@@ -28,7 +28,7 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -38,7 +38,7 @@
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 
--- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Sat Mar 09 21:49:32 2013 +0530
@@ -27,7 +27,7 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Sat Mar 09 21:49:32 2013 +0530
@@ -39,7 +39,7 @@
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -65,8 +65,8 @@
 import jdk.nashorn.internal.objects.DataPropertyDescriptor;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
-import jdk.nashorn.internal.runtime.linker.Lookup;
-import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 
--- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Sat Mar 09 21:49:32 2013 +0530
@@ -27,7 +27,7 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.io.BufferedReader;
 import java.io.File;
--- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,13 +26,13 @@
 package jdk.nashorn.internal.runtime;
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 
--- a/src/jdk/nashorn/internal/runtime/SpillProperty.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/SpillProperty.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,11 +25,11 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 
 /**
  * The SpillProperty is a subclass of AccessorProperties. Anything not in the initial property map
--- a/src/jdk/nashorn/internal/runtime/Undefined.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/Undefined.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.runtime;
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Sat Mar 09 21:49:32 2013 +0530
@@ -26,7 +26,7 @@
 package jdk.nashorn.internal.runtime;
 
 import java.lang.invoke.MethodHandle;
-import jdk.nashorn.internal.runtime.linker.Lookup;
+import jdk.nashorn.internal.lookup.Lookup;
 
 /**
  * Property with user defined getters/setters. Actual getter and setter
--- a/src/jdk/nashorn/internal/runtime/WithObject.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/WithObject.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,6 +25,8 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
+import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -42,7 +44,7 @@
  * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
  * as ScriptObjects from other Nashorn contexts.
  */
-public final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
+final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
    /**
      * Instances of this class are used to represent a method member of a JSObject
      */
--- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Sat Mar 09 21:49:32 2013 +0530
@@ -41,7 +41,7 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
--- a/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Sat Mar 09 21:49:32 2013 +0530
@@ -27,7 +27,7 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,8 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
--- a/src/jdk/nashorn/internal/runtime/linker/Lookup.java	Wed Mar 06 22:38:18 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/*
- * 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 static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import jdk.nashorn.internal.runtime.JSType;
-import jdk.nashorn.internal.runtime.Property;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptRuntime;
-
-/**
- * MethodHandle Lookup management for Nashorn.
- */
-public final class Lookup {
-
-    /**
-     * A global singleton that points to the {@link MethodHandleFunctionality}. This is basically
-     * a collection of wrappers to the standard methods in {@link MethodHandle}, {@link MethodHandles} and
-     * {@link java.lang.invoke.MethodHandles.Lookup}, but instrumentation and debugging purposes we need
-     * intercept points.
-     * <p>
-     * All method handle operations in Nashorn should go through this field, not directly to the classes
-     * in {@code java.lang.invoke}
-     */
-    public static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
-
-    /** Method handle to the empty getter */
-    public static final MethodHandle EMPTY_GETTER = findOwnMH("emptyGetter", Object.class, Object.class);
-
-    /** Method handle to the empty setter */
-    public static final MethodHandle EMPTY_SETTER = findOwnMH("emptySetter", void.class, Object.class, Object.class);
-
-    /** Method handle to a getter that only throws type error */
-    public static final MethodHandle TYPE_ERROR_THROWER_GETTER = findOwnMH("typeErrorThrowerGetter", Object.class, Object.class);
-
-    /** Method handle to a setter that only throws type error */
-    public static final MethodHandle TYPE_ERROR_THROWER_SETTER = findOwnMH("typeErrorThrowerSetter", void.class, Object.class, Object.class);
-
-    /** Method handle to the most generic of getters, the one that returns an Object */
-    public static final MethodType GET_OBJECT_TYPE = MH.type(Object.class, Object.class);
-
-    /** Method handle to the most generic of setters, the one that takes an Object */
-    public static final MethodType SET_OBJECT_TYPE = MH.type(void.class, Object.class, Object.class);
-
-    private Lookup() {
-    }
-
-    /**
-     * Empty getter implementation. Nop
-     * @param self self reference
-     * @return undefined
-     */
-    public static Object emptyGetter(final Object self) {
-        return UNDEFINED;
-    }
-
-    /**
-     * Empty setter implementation. Nop
-     * @param self  self reference
-     * @param value value (ignored)
-     */
-    public static void emptySetter(final Object self, final Object value) {
-        // do nothing!!
-    }
-
-    /**
-     * Return a method handle to the empty getter, with a different
-     * return type value. It will still be undefined cast to whatever
-     * return value property was specified
-     *
-     * @param type return value type
-     *
-     * @return undefined as return value type
-     */
-    public static MethodHandle emptyGetter(final Class<?> type) {
-        return filterReturnType(EMPTY_GETTER, type);
-    }
-
-    /**
-     * Getter function that always throws type error
-     *
-     * @param self  self reference
-     * @return undefined (but throws error before return point)
-     */
-    public static Object typeErrorThrowerGetter(final Object self) {
-        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
-    }
-
-    /**
-     * Getter function that always throws type error
-     *
-     * @param self  self reference
-     * @param value (ignored)
-     */
-    public static void typeErrorThrowerSetter(final Object self, final Object value) {
-        throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self));
-    }
-
-    /**
-     * Create a new {@link Property}
-     *
-     * @param map             property map
-     * @param key             property key
-     * @param flags           property flags
-     * @param propertyGetter  getter for property if available, null otherwise
-     * @param propertySetter  setter for property if available, null otherwise
-     *
-     * @return new property map, representing {@code PropertyMap} with the new property added to it
-     */
-    @SuppressWarnings("fallthrough")
-    public static PropertyMap newProperty(final PropertyMap map, final String key, final int flags, final MethodHandle propertyGetter, final MethodHandle propertySetter) {
-        MethodHandle getter = propertyGetter;
-        MethodHandle setter = propertySetter;
-
-        // TODO: this is temporary code. This code exists to support reflective
-        // field reader/writer handles generated by "unreflect" lookup.
-
-        switch (getter.type().parameterCount()) {
-        case 0:
-            // A static field reader, so drop the 'self' argument.
-            getter = MH.dropArguments(getter, 0, Object.class);
-            if (setter != null) {
-                setter = MH.dropArguments(setter, 0, Object.class);
-            }
-        // fall through
-        case 1:
-            // standard getter that accepts 'self'.
-            break;
-        default:
-            // Huh!! something wrong..
-            throw new IllegalArgumentException("getter/setter has wrong arguments");
-        }
-
-        return map.newProperty(key, flags, -1, getter, setter);
-    }
-
-    /**
-     * This method filters primitive return types using JavaScript semantics. For example,
-     * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it.
-     * If you are returning values to JavaScript that have to be of a specific type, this is
-     * the correct return value filter to use, as the explicitCastArguments just uses the
-     * Java boxing equivalents
-     *
-     * @param mh   method handle for which to filter return value
-     * @param type new return type
-     * @return method handle for appropriate return type conversion
-     */
-    public static MethodHandle filterReturnType(final MethodHandle mh, final Class<?> type) {
-        final Class<?> retType = mh.type().returnType();
-
-        if (retType == int.class) {
-            //fallthru
-        } else if (retType == long.class) {
-            //fallthru
-        } else if (retType == double.class) {
-            if (type == int.class) {
-                return MH.filterReturnValue(mh, JSType.TO_INT32_D.methodHandle());
-            } else if (type == long.class) {
-                return MH.filterReturnValue(mh, JSType.TO_UINT32_D.methodHandle());
-            }
-            //fallthru
-        } else if (!retType.isPrimitive()) {
-            if (type == int.class) {
-                return MH.filterReturnValue(mh, JSType.TO_INT32.methodHandle());
-            } else if (type == long.class) {
-                return MH.filterReturnValue(mh, JSType.TO_UINT32.methodHandle());
-            } else if (type == double.class) {
-                return MH.filterReturnValue(mh, JSType.TO_NUMBER.methodHandle());
-            } else if (!type.isPrimitive()) {
-                return mh;
-            }
-
-            assert false : "unsupported Lookup.filterReturnType type " + retType + " -> " + type;
-        }
-
-        //use a standard cast - we don't need to check JavaScript special cases
-        return MH.explicitCastArguments(mh, mh.type().changeReturnType(type));
-    }
-
-    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
-        return MH.findStatic(MethodHandles.lookup(), Lookup.class, name, MH.type(rtype, types));
-    }
-
-}
--- a/src/jdk/nashorn/internal/runtime/linker/MethodHandleFactory.java	Wed Mar 06 22:38:18 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,646 +0,0 @@
-/*
- * 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.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.SwitchPoint;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.logging.Level;
-import jdk.nashorn.internal.runtime.ConsString;
-import jdk.nashorn.internal.runtime.Debug;
-import jdk.nashorn.internal.runtime.DebugLogger;
-import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.options.Options;
-
-/**
- * This class is abstraction for all method handle, switchpoint and method type
- * operations. This enables the functionality interface to be subclassed and
- * intrumensted, as it has been proven vital to keep the number of method
- * handles in the system down.
- *
- * All operations of the above type should go through this class, and not
- * directly into java.lang.invoke
- *
- */
-public final class MethodHandleFactory {
-
-    private static final MethodHandles.Lookup PUBLIC_LOOKUP = MethodHandles.publicLookup();
-    private static final MethodHandles.Lookup LOOKUP        = MethodHandles.lookup();
-
-    private static final Level TRACE_LEVEL = Level.INFO;
-
-    private MethodHandleFactory() {
-    }
-
-    /**
-     * Runtime exception that collects every reason that a method handle lookup operation can go wrong
-     */
-    @SuppressWarnings("serial")
-    public static class LookupException extends RuntimeException {
-        /**
-         * Constructor
-         * @param e causing exception
-         */
-        public LookupException(final Exception e) {
-            super(e);
-        }
-    }
-
-    /**
-     * Helper function that takes a class or an object with a toString override
-     * and shortens it to notation after last dot. This is used to facilitiate
-     * pretty printouts in various debug loggers - internal only
-     *
-     * @param obj class or object
-     *
-     * @return pretty version of object as string
-     */
-    public static String stripName(final Object obj) {
-        if (obj == null) {
-            return "null";
-        }
-
-        if (obj instanceof Class) {
-            return ((Class<?>)obj).getSimpleName();
-        }
-        return obj.toString();
-    }
-
-    private static final MethodHandleFunctionality STANDARD = new StandardMethodHandleFunctionality();
-    private static final MethodHandleFunctionality FUNC;
-
-    private static final String DEBUG_PROPERTY = "nashorn.methodhandles.debug";
-    private static final DebugLogger LOG = new DebugLogger("methodhandles", DEBUG_PROPERTY);
-
-    static {
-        if (LOG.isEnabled() || Options.getBooleanProperty(DEBUG_PROPERTY)) {
-            if (Options.getStringProperty(DEBUG_PROPERTY, "").equals("create")) {
-                FUNC = new TraceCreateMethodHandleFunctionality();
-            } else {
-                FUNC = new TraceMethodHandleFunctionality();
-            }
-        } else {
-            FUNC  = STANDARD;
-        }
-    }
-
-    private static final boolean PRINT_STACKTRACE = Options.getBooleanProperty("nashorn.methodhandles.debug.stacktrace");
-
-
-    /**
-     * Return the method handle functionality used for all method handle operations
-     * @return a method handle functionality implementation
-     */
-    public static MethodHandleFunctionality getFunctionality() {
-        return FUNC;
-    }
-
-    private static final MethodHandle TRACE        = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs",   MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
-    private static final MethodHandle TRACE_RETURN = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
-
-    /**
-     * Tracer that is applied before a value is returned from the traced function. It will output the return
-     * value and its class
-     *
-     * @param value return value for filter
-     * @return return value unmodified
-     */
-    static Object traceReturn(final DebugLogger logger, final Object value) {
-        final String str = "\treturn: " + stripName(value) + " [type=" + (value == null ? "null" : stripName(value.getClass()) + ']');
-        logger.log(str, TRACE_LEVEL);
-        return value;
-    }
-
-    /**
-     * Tracer that is applied before a function is called, printing the arguments
-     *
-     * @param tag  tag to start the debug printout string
-     * @param paramStart param index to start outputting from
-     * @param args arguments to the function
-     */
-    static void traceArgs(final DebugLogger logger, final String tag, final int paramStart, final Object... args) {
-        final StringBuilder sb = new StringBuilder();
-
-        sb.append(tag);
-
-        for (int i = paramStart; i < args.length; i++) {
-            if (i == paramStart) {
-                sb.append(" => args: ");
-            }
-
-            sb.append('\'').
-                append(stripName(argString(args[i]))).
-                append('\'').
-                append(' ').
-                append('[').
-                append("type=").
-                append(args[i] == null ? "null" : stripName(args[i].getClass())).
-                append(']');
-
-            if (i + 1 < args.length) {
-                sb.append(", ");
-            }
-        }
-
-        assert logger != null;
-        logger.log(sb.toString(), TRACE_LEVEL);
-        stacktrace(logger);
-    }
-
-    private static void stacktrace(final DebugLogger logger) {
-        if (!PRINT_STACKTRACE) {
-            return;
-        }
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final PrintStream ps = new PrintStream(baos);
-        new Throwable().printStackTrace(ps);
-        logger.log(baos.toString(), TRACE_LEVEL);
-    }
-
-    private static String argString(final Object arg) {
-        if (arg == null) {
-            return "null";
-        }
-
-        if (arg.getClass().isArray()) {
-            final List<Object> list = new ArrayList<>();
-            for (final Object elem : (Object[])arg) {
-                list.add('\'' + argString(elem) + '\'');
-            }
-
-            return list.toString();
-        }
-
-        if (arg instanceof ScriptObject) {
-            return arg.toString() +
-                " (map=" + Debug.id((((ScriptObject)arg).getMap())) +
-                ")";
-        }
-
-        return arg.toString();
-    }
-
-    /**
-     * Add a debug printout to a method handle, tracing parameters and return values
-     *
-     * @param logger a specific logger to which to write the output
-     * @param mh  method handle to trace
-     * @param tag start of trace message
-     * @return traced method handle
-     */
-    public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final Object tag) {
-        return addDebugPrintout(logger, mh, 0, true, tag);
-    }
-
-
-    /**
-     * Add a debug printout to a method handle, tracing parameters and return values
-     *
-     * @param logger a specific logger to which to write the output
-     * @param mh  method handle to trace
-     * @param paramStart first param to print/trace
-     * @param printReturnValue should we print/trace return value if available?
-     * @param tag start of trace message
-     * @return  traced method handle
-     */
-    public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
-        final MethodType type = mh.type();
-
-        if (logger != null && logger.levelAbove(TRACE_LEVEL)) {
-            return mh;
-        }
-
-        assert logger != null;
-        assert TRACE != null;
-
-        MethodHandle trace = MethodHandles.insertArguments(TRACE, 0, logger, tag, paramStart);
-
-        trace = MethodHandles.foldArguments(
-                mh,
-                trace.asCollector(
-                    Object[].class,
-                    type.parameterCount()).
-                asType(type.changeReturnType(void.class)));
-
-        final Class<?> retType = type.returnType();
-        if (retType != void.class && printReturnValue) {
-            final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
-            trace = MethodHandles.filterReturnValue(trace,
-                    traceReturn.asType(
-                        traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
-        }
-
-        return trace;
-    }
-
-    /**
-     * The standard class that marshalls all method handle operations to the java.lang.invoke
-     * package. This exists only so that it can be subclassed and method handles created from
-     * Nashorn made possible to instrument.
-     *
-     * All Nashorn classes should use the MethodHandleFactory for their method handle operations
-     */
-    private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality {
-
-        @Override
-        public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
-            return MethodHandles.filterArguments(target, pos, filters);
-        }
-
-        @Override
-        public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
-            return MethodHandles.filterReturnValue(target, filter);
-        }
-
-        @Override
-        public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
-            return MethodHandles.guardWithTest(test, target, fallback);
-        }
-
-        @Override
-        public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
-            return MethodHandles.insertArguments(target, pos, values);
-        }
-
-        @Override
-        public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
-            return MethodHandles.dropArguments(target, pos, valueTypes);
-        }
-
-        @Override
-        public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes) {
-            return MethodHandles.dropArguments(target, pos, valueTypes);
-        }
-
-        @Override
-        public MethodHandle asType(final MethodHandle handle, final MethodType type) {
-            return handle.asType(type);
-        }
-
-        @Override
-        public MethodHandle bindTo(final MethodHandle handle, final Object x) {
-            return handle.bindTo(x);
-        }
-
-        @Override
-        public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
-            return MethodHandles.foldArguments(target, combiner);
-        }
-
-        @Override
-        public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
-            return MethodHandles.explicitCastArguments(target, type);
-        }
-
-        @Override
-        public MethodHandle arrayElementGetter(final Class<?> type) {
-            return MethodHandles.arrayElementGetter(type);
-        }
-
-        @Override
-        public MethodHandle arrayElementSetter(final Class<?> type) {
-            return MethodHandles.arrayElementSetter(type);
-        }
-
-        @Override
-        public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
-            return MethodHandles.throwException(returnType, exType);
-        }
-
-        @Override
-        public MethodHandle constant(final Class<?> type, final Object value) {
-            return MethodHandles.constant(type, value);
-        }
-
-        @Override
-        public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
-            return handle.asCollector(arrayType, arrayLength);
-        }
-
-        @Override
-        public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
-            return handle.asSpreader(arrayType, arrayLength);
-        }
-
-        @Override
-        public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            try {
-                return explicitLookup.findGetter(clazz, name, type);
-            } catch (final NoSuchFieldException | IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-        @Override
-        public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            try {
-                return explicitLookup.findStaticGetter(clazz, name, type);
-            } catch (final NoSuchFieldException | IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-
-        @Override
-        public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            try {
-                return explicitLookup.findSetter(clazz, name, type);
-            } catch (final NoSuchFieldException | IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-        @Override
-        public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            try {
-                return explicitLookup.findStaticSetter(clazz, name, type);
-            } catch (final NoSuchFieldException | IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-        @Override
-        public MethodHandle find(final Method method) {
-            try {
-                return PUBLIC_LOOKUP.unreflect(method);
-            } catch (final IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-        @Override
-        public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
-            try {
-                return explicitLookup.findStatic(clazz, name, type);
-            } catch (final NoSuchMethodException | IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-        @Override
-        public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
-            try {
-                return explicitLookup.findVirtual(clazz, name, type);
-            } catch (final NoSuchMethodException | IllegalAccessException e) {
-                throw new LookupException(e);
-            }
-        }
-
-        @Override
-        public SwitchPoint createSwitchPoint() {
-            return new SwitchPoint();
-        }
-
-        @Override
-        public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
-            return sp.guardWithTest(before, after);
-        }
-
-        @Override
-        public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
-            return MethodType.methodType(returnType, paramTypes);
-        }
-
-    }
-
-    /**
-     * Class used for instrumenting and debugging Nashorn generated method handles
-     */
-    private static class TraceMethodHandleFunctionality extends StandardMethodHandleFunctionality {
-
-        protected static String describe(final Object... data) {
-            final StringBuilder sb = new StringBuilder();
-
-            for (int i = 0; i < data.length; i++) {
-                final Object d = data[i];
-                if (d == null) {
-                    sb.append("<null> ");
-                } else if (d instanceof String || d instanceof ConsString) {
-                    sb.append(d.toString());
-                    sb.append(' ');
-                } else if (d.getClass().isArray()) {
-                    sb.append("[ ");
-                    for (final Object da : (Object[])d) {
-                        sb.append(describe(new Object[]{ da })).append(' ');
-                    }
-                    sb.append("] ");
-                } else {
-                    sb.append(d)
-                        .append('{')
-                        .append(Integer.toHexString(System.identityHashCode(d)))
-                        .append('}');
-                }
-
-                if (i + 1 < data.length) {
-                    sb.append(", ");
-                }
-            }
-
-            return sb.toString();
-        }
-
-        public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
-            return addDebugPrintout(LOG, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
-        }
-
-        @Override
-        public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
-            final MethodHandle mh = super.filterArguments(target, pos, filters);
-            return debug(mh, "filterArguments", target, pos, filters);
-        }
-
-        @Override
-        public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
-            final MethodHandle mh = super.filterReturnValue(target, filter);
-            return debug(mh, "filterReturnValue", target, filter);
-        }
-
-        @Override
-        public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
-            final MethodHandle mh = super.guardWithTest(test, target, fallback);
-            return debug(mh, "guardWithTest", test, target, fallback);
-        }
-
-        @Override
-        public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
-            final MethodHandle mh = super.insertArguments(target, pos, values);
-            return debug(mh, "insertArguments", target, pos, values);
-        }
-
-        @Override
-        public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
-            final MethodHandle mh = super.dropArguments(target, pos, values);
-            return debug(mh, "dropArguments", target, pos, values);
-        }
-
-        @Override
-        public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
-            final MethodHandle mh = super.dropArguments(target, pos, values);
-            return debug(mh, "dropArguments", target, pos, values);
-        }
-
-        @Override
-        public MethodHandle asType(final MethodHandle handle, final MethodType type) {
-            final MethodHandle mh = super.asType(handle, type);
-            return debug(mh, "asType", handle, type);
-        }
-
-        @Override
-        public MethodHandle bindTo(final MethodHandle handle, final Object x) {
-            final MethodHandle mh = super.bindTo(handle, x);
-            return debug(mh, "bindTo", handle, x);
-        }
-
-        @Override
-        public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
-            final MethodHandle mh = super.foldArguments(target, combiner);
-            return debug(mh, "foldArguments", target, combiner);
-        }
-
-        @Override
-        public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
-            final MethodHandle mh = super.explicitCastArguments(target, type);
-            return debug(mh, "explicitCastArguments", target, type);
-        }
-
-        @Override
-        public MethodHandle arrayElementGetter(final Class<?> type) {
-            final MethodHandle mh = super.arrayElementGetter(type);
-            return debug(mh, "arrayElementGetter", type);
-        }
-
-        @Override
-        public MethodHandle arrayElementSetter(final Class<?> type) {
-            final MethodHandle mh = super.arrayElementSetter(type);
-            return debug(mh, "arrayElementSetter", type);
-        }
-
-        @Override
-        public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
-            final MethodHandle mh = super.throwException(returnType, exType);
-            return debug(mh, "throwException", returnType, exType);
-        }
-
-        @Override
-        public MethodHandle constant(final Class<?> type, final Object value) {
-            final MethodHandle mh = super.constant(type, value);
-            return debug(mh, "constant", type, value);
-        }
-
-        @Override
-        public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
-            final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
-            return debug(mh, "asCollector", handle, arrayType, arrayLength);
-        }
-
-        @Override
-        public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
-            final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
-            return debug(mh, "asSpreader", handle, arrayType, arrayLength);
-        }
-
-        @Override
-        public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            final MethodHandle mh = super.getter(explicitLookup, clazz, name, type);
-            return debug(mh, "getter", explicitLookup, clazz, name, type);
-        }
-
-        @Override
-        public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            final MethodHandle mh = super.staticGetter(explicitLookup, clazz, name, type);
-            return debug(mh, "static getter", explicitLookup, clazz, name, type);
-        }
-
-        @Override
-        public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            final MethodHandle mh = super.setter(explicitLookup, clazz, name, type);
-            return debug(mh, "setter", explicitLookup, clazz, name, type);
-        }
-
-        @Override
-        public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
-            final MethodHandle mh = super.staticSetter(explicitLookup, clazz, name, type);
-            return debug(mh, "static setter", explicitLookup, clazz, name, type);
-        }
-
-        @Override
-        public MethodHandle find(final Method method) {
-            final MethodHandle mh = super.find(method);
-            return debug(mh, "find", method);
-        }
-
-        @Override
-        public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
-            final MethodHandle mh = super.findStatic(explicitLookup, clazz, name, type);
-            return debug(mh, "findStatic", explicitLookup, clazz, name, type);
-        }
-
-        @Override
-        public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
-            final MethodHandle mh = super.findVirtual(explicitLookup, clazz, name, type);
-            return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
-        }
-
-        @Override
-        public SwitchPoint createSwitchPoint() {
-            final SwitchPoint sp = super.createSwitchPoint();
-            LOG.log("createSwitchPoint " + sp, TRACE_LEVEL);
-            return sp;
-        }
-
-        @Override
-        public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
-            final MethodHandle mh = super.guardWithTest(sp, before, after);
-            return debug(mh, "guardWithTest", sp, before, after);
-        }
-
-        @Override
-        public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
-            final MethodType mt = super.type(returnType, paramTypes);
-            LOG.log("methodType " + returnType + ' ' + Arrays.toString(paramTypes) + ' ' + mt, TRACE_LEVEL);
-            return mt;
-        }
-    }
-
-    /**
-     * Class used for debugging Nashorn generated method handles
-     */
-    private static class TraceCreateMethodHandleFunctionality extends TraceMethodHandleFunctionality {
-        @Override
-        public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
-            LOG.log(str + ' ' + describe(args), TRACE_LEVEL);
-            stacktrace(LOG);
-            return master;
-        }
-    }
-}
--- a/src/jdk/nashorn/internal/runtime/linker/MethodHandleFunctionality.java	Wed Mar 06 22:38:18 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * 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 java.lang.invoke.SwitchPoint;
-import java.lang.reflect.Method;
-import java.util.List;
-
-/**
- * Wrapper for all method handle related functions used in Nashorn. This interface only exists
- * so that instrumentation can be added to all method handle operations.
- */
-
-public interface MethodHandleFunctionality {
-    /**
-     * Wrapper for {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}
-     *
-     * @param target  target method handle
-     * @param pos     start argument index
-     * @param filters filters
-     *
-     * @return filtered handle
-     */
-    public MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters);
-
-    /**
-     * Wrapper for {@link MethodHandles#filterReturnValue(MethodHandle, MethodHandle)}
-     *
-     * @param target  target method handle
-     * @param filter  filter
-     *
-     * @return filtered handle
-     */
-    public MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter);
-
-    /**
-     * Wrapper for {@link MethodHandles#guardWithTest(MethodHandle, MethodHandle, MethodHandle)}
-     *
-     * @param test     test method handle
-     * @param target   target method handle when test is true
-     * @param fallback fallback method handle when test is false
-     *
-     * @return guarded handles
-     */
-    public MethodHandle guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback);
-
-    /**
-     * Wrapper for {@link MethodHandles#insertArguments(MethodHandle, int, Object...)}
-     *
-     * @param target target method handle
-     * @param pos    start argument index
-     * @param values values to insert
-     *
-     * @return handle with bound arguments
-     */
-    public MethodHandle insertArguments(MethodHandle target, int pos, Object... values);
-
-    /**
-     * Wrapper for {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}
-     *
-     * @param target     target method handle
-     * @param pos        start argument index
-     * @param valueTypes valueTypes of arguments to drop
-     *
-     * @return handle with dropped arguments
-     */
-    public MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes);
-
-    /**
-     * Wrapper for {@link MethodHandles#dropArguments(MethodHandle, int, List)}
-     *
-     * @param target     target method handle
-     * @param pos        start argument index
-     * @param valueTypes valueTypes of arguments to drop
-     *
-     * @return handle with dropped arguments
-     */
-    public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes);
-
-    /**
-     * Wrapper for {@link MethodHandles#foldArguments(MethodHandle, MethodHandle)}
-     *
-     * @param target   target method handle
-     * @param combiner combiner to apply for fold
-     *
-     * @return folded method handle
-     */
-    public MethodHandle foldArguments(MethodHandle target, MethodHandle combiner);
-
-    /**
-     * Wrapper for {@link MethodHandles#explicitCastArguments(MethodHandle, MethodType)}
-     *
-     * @param target  target method handle
-     * @param type    type to cast to
-     *
-     * @return modified method handle
-     */
-    public MethodHandle explicitCastArguments(MethodHandle target, MethodType type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles#arrayElementGetter(Class)}
-     *
-     * @param arrayClass class for array
-     *
-     * @return array element getter
-     */
-    public MethodHandle arrayElementGetter(Class<?> arrayClass);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles#arrayElementSetter(Class)}
-     *
-     * @param arrayClass class for array
-     *
-     * @return array element setter
-     */
-    public MethodHandle arrayElementSetter(Class<?> arrayClass);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles#throwException(Class, Class)}
-     *
-     * @param returnType ignored, but method signature will use it
-     * @param exType     exception type that will be thrown
-     *
-     * @return exception thrower method handle
-     */
-    public MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles#constant(Class, Object)}
-     *
-     * @param type  type of constant
-     * @param value constant value
-     *
-     * @return method handle that returns said constant
-     */
-    public MethodHandle constant(Class<?> type, Object value);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandle#asType(MethodType)}
-     *
-     * @param handle  method handle for type conversion
-     * @param type    type to convert to
-     *
-     * @return method handle with given type conversion applied
-     */
-    public MethodHandle asType(MethodHandle handle, MethodType type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandle#asCollector(Class, int)}
-     *
-     * @param handle      handle to convert
-     * @param arrayType   array type for collector array
-     * @param arrayLength length of collector array
-     *
-     * @return method handle with collector
-     */
-    public MethodHandle asCollector(MethodHandle handle, Class<?> arrayType, int arrayLength);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandle#asSpreader(Class, int)}
-     *
-     * @param handle      handle to convert
-     * @param arrayType   array type for spread
-     * @param arrayLength length of spreader
-     *
-     * @return method handle as spreader
-     */
-    public MethodHandle asSpreader(MethodHandle handle, Class<?> arrayType, int arrayLength);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandle#bindTo(Object)}
-     *
-     * @param handle a handle to which to bind a receiver
-     * @param x      the receiver
-     *
-     * @return the bound handle
-     */
-    public MethodHandle bindTo(MethodHandle handle, Object x);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}
-      *
-     * @param explicitLookup explicit lookup to be used
-     * @param clazz          class to look in
-     * @param name           name of field
-     * @param type           type of field
-     *
-     * @return getter method handle for virtual field
-     */
-    public MethodHandle getter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter(Class, String, Class)}
-      *
-     * @param explicitLookup explicit lookup to be used
-     * @param clazz          class to look in
-     * @param name           name of field
-     * @param type           type of field
-     *
-     * @return getter method handle for static field
-     */
-    public MethodHandle staticGetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findSetter(Class, String, Class)}
-      *
-     * @param explicitLookup explicit lookup to be used
-     * @param clazz          class to look in
-     * @param name           name of field
-     * @param type           type of field
-     *
-     * @return setter method handle for virtual field
-     */
-    public MethodHandle setter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter(Class, String, Class)}
-      *
-     * @param explicitLookup explicit lookup to be used
-     * @param clazz          class to look in
-     * @param name           name of field
-     * @param type           type of field
-     *
-     * @return setter method handle for static field
-     */
-    public MethodHandle staticSetter(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, Class<?> type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}
-     *
-     * Unreflect a method as a method handle
-     *
-     * @param method method to unreflect
-     * @return unreflected method as method handle
-     */
-    public MethodHandle find(Method method);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findStatic(Class, String, MethodType)}
-     *
-     * @param explicitLookup explicit lookup to be used
-     * @param clazz          class to look in
-     * @param name           name of method
-     * @param type           method type
-     *
-     * @return method handle for static method
-     */
-    public MethodHandle findStatic(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
-
-    /**
-     * Wrapper for {@link java.lang.invoke.MethodHandles.Lookup#findVirtual(Class, String, MethodType)}
-     *
-     * @param explicitLookup explicit lookup to be used
-     * @param clazz          class to look in
-     * @param name           name of method
-     * @param type           method type
-     *
-     * @return method handle for virtual method
-     */
-    public MethodHandle findVirtual(MethodHandles.Lookup explicitLookup, Class<?> clazz, String name, MethodType type);
-
-    /**
-     * Wrapper for SwitchPoint creation. Just like {@code new SwitchPoint()} but potentially
-     * tracked
-     *
-     * @return new switch point
-     */
-    public SwitchPoint createSwitchPoint();
-
-    /**
-     * Wrapper for {@link SwitchPoint#guardWithTest(MethodHandle, MethodHandle)}
-     *
-     * @param sp     switch point
-     * @param before method handle when switchpoint is valid
-     * @param after  method handle when switchpoint is invalidated
-     *
-     * @return guarded method handle
-     */
-    public MethodHandle guardWithTest(SwitchPoint sp, MethodHandle before, MethodHandle after);
-
-    /**
-     * Wrapper for {@link MethodType#methodType(Class, Class...)}
-     *
-     * @param returnType  return type for method type
-     * @param paramTypes  parameter types for method type
-     *
-     * @return the method type
-     */
-    public MethodType type(Class<?> returnType, Class<?>... paramTypes);
-}
-
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Sat Mar 09 21:49:32 2013 +0530
@@ -27,7 +27,7 @@
 
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import jdk.internal.dynalink.CallSiteDescriptor;
@@ -46,7 +46,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.
  */
-class NashornBottomLinker implements GuardingDynamicLinker {
+final class NashornBottomLinker implements GuardingDynamicLinker {
 
     @Override
     public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
--- a/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
--- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -47,7 +47,7 @@
  * language runtimes by being declared in {@code META-INF/services/jdk.internal.dynalink.linker.GuardingDynamicLinker}
  * file of Nashorn's distribution.
  */
-public class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
+final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
     /**
      * Returns true if {@code ScriptObject} is assignable from {@code type}, or it is {@code Undefined}.
      */
--- a/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,7 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
@@ -45,7 +45,7 @@
  * engines. It is used for treatment of strings, boolean, and numbers as JavaScript primitives. Also provides ECMAScript
  * primitive type conversions for these types when linking to Java methods.
  */
-class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
+final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
     @Override
     public boolean canLinkType(final Class<?> type) {
         return canLinkTypeStatic(type);
--- a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Sat Mar 09 21:49:32 2013 +0530
@@ -48,7 +48,7 @@
  *   var r = new Runnable(function() { print("Hello World" })
  * </pre>
  */
-class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
+final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
     private static final GuardingDynamicLinker staticClassLinker = BeansLinker.getLinkerForClass(StaticClass.class);
 
     @Override
--- a/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Wed Mar 06 22:38:18 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Sat Mar 09 21:49:32 2013 +0530
@@ -25,7 +25,8 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+import jdk.nashorn.internal.lookup.Lookup;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/currently-failing/JDK-8006529.js	Sat Mar 09 21:49:32 2013 +0530
@@ -0,0 +1,210 @@
+/*
+ * 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-8006529 : Methods should not always get callee parameter, and they
+ * should not be too eager in creation of scopes.
+ *
+ * @test
+ * @run
+ */
+
+/*
+ * This test script depends on nashorn Compiler internals. It uses reflection
+ * to get access to private field and many public methods of Compiler and
+ * FunctionNode classes. Note that this is trusted code and access to such
+ * internal package classes and methods is okay. But, if you modify any 
+ * Compiler or FunctionNode class, you may have to revisit this script.
+ * We cannot use direct Java class (via dynalink bean linker) to Compiler
+ * and FunctionNode because of package-access check and so reflective calls.
+ */
+
+var Parser         = Java.type("jdk.nashorn.internal.parser.Parser")
+var Compiler       = Java.type("jdk.nashorn.internal.codegen.Compiler")
+var Context        = Java.type("jdk.nashorn.internal.runtime.Context")
+var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment")
+var Source         = Java.type("jdk.nashorn.internal.runtime.Source")
+var FunctionNode   = Java.type("jdk.nashorn.internal.ir.FunctionNode")
+
+// Compiler class methods and fields
+var parseMethod = Parser.class.getMethod("parse");
+var compileMethod = Compiler.class.getMethod("compile");
+
+// NOTE: private field. But this is a trusted test!
+// Compiler.functionNode
+var functionNodeField = Compiler.class.getDeclaredField("functionNode");
+functionNodeField.setAccessible(true);
+
+// FunctionNode methods
+
+// FunctionNode.getFunctions method
+var getFunctionsMethod = FunctionNode.class.getMethod("getFunctions");
+
+// These are method names of methods in FunctionNode class
+var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope', 'isStrictMode']
+
+// corresponding Method objects of FunctionNode class
+var functionNodeMethods = {};
+// initialize FunctionNode methods
+(function() {
+    for (var f in allAssertionList) {
+        var method = allAssertionList[f];
+        functionNodeMethods[method] = FunctionNode.class.getMethod(method);
+    }
+})();
+
+// returns "script" functionNode from Compiler instance
+function getScriptNode(compiler) {
+    // compiler.functionNode
+    return functionNodeField.get(compiler);
+}
+
+// returns functionNode.getFunctions().get(0)
+function getFirstFunction(functionNode) {
+    // functionNode.getFunctions().get(0)
+    return getFunctionsMethod.invoke(functionNode).get(0);
+}
+
+// compile(script) -- compiles a script specified as a string with its 
+// source code, returns a jdk.nashorn.internal.ir.FunctionNode object 
+// representing it.
+function compile(source) {
+    var source   = new Source("<no name>", source);
+    var parser   = new Parser(Context.getContext().getEnv(), source, null);
+    var func     = parseMethod.invoke(parser);
+    var compiler = new Compiler(Context.getContext().getEnv(), func);
+
+    compileMethod.invoke(compiler);
+
+    return getScriptNode(compiler);
+};
+
+var allAssertions = (function() {
+    var allAssertions = {}
+    for(var assertion in allAssertionList) {
+        allAssertions[allAssertionList[assertion]] = true
+    }
+    return allAssertions;
+})();
+
+
+// test(f[, assertions...]) tests whether all the specified assertions on the
+// passed function node are true.
+function test(f) {
+    var assertions = {}
+    for(var i = 1; i < arguments.length; ++i) {
+        var assertion = arguments[i]
+        if(!allAssertions[assertion]) {
+            throw "Unknown assertion " + assertion + " for " + f;
+        }
+        assertions[assertion] = true
+    }
+    for(var assertion in allAssertions) {
+        var expectedValue = !!assertions[assertion]
+        if(functionNodeMethods[assertion].invoke(f) !== expectedValue) {
+            throw "Expected " + assertion + " === " + expectedValue + " for " + f;
+        }
+    }
+}
+
+// testFirstFn(script[, assertions...] tests whether all the specified
+// assertions are true in the first function in the given script; "script"
+// is a string with the source text of the script.
+function testFirstFn(script) {
+    arguments[0] = getFirstFunction(compile(script))
+    test.apply(null, arguments)
+}
+
+// ---------------------------------- ACTUAL TESTS START HERE --------------
+
+// The simplest possible functions have no attributes set
+testFirstFn("function f() { }")
+testFirstFn("function f(x) { x }")
+
+// A function referencing a global needs parent scope, and it needs callee
+// (because parent scope is passed through callee)
+testFirstFn("function f() { x }", 'needsCallee', 'needsParentScope')
+
+// A function referencing "arguments" will have to be vararg. It also needs
+// the callee, as it needs to fill out "arguments.callee".
+testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg')
+
+// A function referencing "arguments" will have to be vararg. If it is
+// strict, it will not have to have a callee, though.
+testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrictMode')
+
+// A function defining "arguments" as a parameter will not be vararg.
+testFirstFn("function f(arguments) { arguments }")
+
+// A function defining "arguments" as a nested function will not be vararg.
+testFirstFn("function f() { function arguments() {}; arguments; }")
+
+// A function defining "arguments" as a local variable will be vararg.
+testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')
+
+// A self-referencing function defined as a statement doesn't need a self 
+// symbol, as it'll rather obtain itself from the parent scope.
+testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')
+
+// A self-referencing function defined as an expression needs a self symbol,
+// as it can't obtain itself from the parent scope.
+testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol')
+
+// A child function accessing parent's variable triggers the need for scope
+// in parent
+testFirstFn("(function f() { var x; function g() { x } })", 'needsScope')
+
+// A child function accessing parent's parameter triggers the need for scope
+// in parent
+testFirstFn("(function f(x) { function g() { x } })", 'needsScope')
+
+// A child function accessing a global variable triggers the need for parent
+// scope in parent
+testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')
+
+// A child function redefining a local variable from its parent should not 
+// affect the parent function in any way
+testFirstFn("(function f() { var x; function g() { var x; x } })")
+
+// Using "with" unleashes a lot of needs: parent scope, callee, own scope, 
+// and all variables in scope. Actually, we could make "with" less wasteful,
+// and only put those variables in scope that it actually references, similar
+// to what nested functions do with variables in their parents.
+testFirstFn("(function f() { var o; with(o) {} })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope')
+
+// Using "eval" is as bad as using "with" with the added requirement of
+// being vararg, 'cause we don't know if eval will be using "arguments".
+testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasEval', 'isVarArg', 'hasDeepWithOrEval', 'allVarsInScope')
+
+// Nested function using "with" is pretty much the same as the parent
+// function needing with.
+testFirstFn("(function f() { function g() { var o; with(o) {} } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope')
+// Nested function using "eval" is almost the same as parent function using
+// eval, but at least the parent doesn't have to be vararg.
+testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope')
+
+// Function with 250 named parameters is ordinary
+testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }")
+
+// Function with 251 named parameters is variable arguments
+testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg')
--- a/test/script/trusted/JDK-8006529.js	Wed Mar 06 22:38:18 2013 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
- * 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-8006529 : Methods should not always get callee parameter, and they
- * should not be too eager in creation of scopes.
- *
- * @test
- * @run
- */
-
-/*
- * This test script depends on nashorn Compiler internals. It uses reflection
- * to get access to private field and many public methods of Compiler and
- * FunctionNode classes. Note that this is trusted code and access to such
- * internal package classes and methods is okay. But, if you modify any 
- * Compiler or FunctionNode class, you may have to revisit this script.
- * We cannot use direct Java class (via dynalink bean linker) to Compiler
- * and FunctionNode because of package-access check and so reflective calls.
- */
-
-var Parser         = Java.type("jdk.nashorn.internal.parser.Parser")
-var Compiler       = Java.type("jdk.nashorn.internal.codegen.Compiler")
-var Context        = Java.type("jdk.nashorn.internal.runtime.Context")
-var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment")
-var Source         = Java.type("jdk.nashorn.internal.runtime.Source")
-var FunctionNode   = Java.type("jdk.nashorn.internal.ir.FunctionNode")
-
-// Compiler class methods and fields
-var parseMethod = Parser.class.getMethod("parse");
-var compileMethod = Compiler.class.getMethod("compile");
-
-// NOTE: private field. But this is a trusted test!
-// Compiler.functionNode
-var functionNodeField = Compiler.class.getDeclaredField("functionNode");
-functionNodeField.setAccessible(true);
-
-// FunctionNode methods
-
-// FunctionNode.getFunctions method
-var getFunctionsMethod = FunctionNode.class.getMethod("getFunctions");
-
-// These are method names of methods in FunctionNode class
-var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope', 'isStrictMode']
-
-// corresponding Method objects of FunctionNode class
-var functionNodeMethods = {};
-// initialize FunctionNode methods
-(function() {
-    for (var f in allAssertionList) {
-        var method = allAssertionList[f];
-        functionNodeMethods[method] = FunctionNode.class.getMethod(method);
-    }
-})();
-
-// returns "script" functionNode from Compiler instance
-function getScriptNode(compiler) {
-    // compiler.functionNode
-    return functionNodeField.get(compiler);
-}
-
-// returns functionNode.getFunctions().get(0)
-function getFirstFunction(functionNode) {
-    // functionNode.getFunctions().get(0)
-    return getFunctionsMethod.invoke(functionNode).get(0);
-}
-
-// compile(script) -- compiles a script specified as a string with its 
-// source code, returns a jdk.nashorn.internal.ir.FunctionNode object 
-// representing it.
-function compile(source) {
-    var source   = new Source("<no name>", source);
-    var parser   = new Parser(Context.getContext().getEnv(), source, null);
-    var func     = parseMethod.invoke(parser);
-    var compiler = new Compiler(Context.getContext().getEnv(), func);
-
-    compileMethod.invoke(compiler);
-
-    return getScriptNode(compiler);
-};
-
-var allAssertions = (function() {
-    var allAssertions = {}
-    for(var assertion in allAssertionList) {
-        allAssertions[allAssertionList[assertion]] = true
-    }
-    return allAssertions;
-})();
-
-
-// test(f[, assertions...]) tests whether all the specified assertions on the
-// passed function node are true.
-function test(f) {
-    var assertions = {}
-    for(var i = 1; i < arguments.length; ++i) {
-        var assertion = arguments[i]
-        if(!allAssertions[assertion]) {
-            throw "Unknown assertion " + assertion + " for " + f;
-        }
-        assertions[assertion] = true
-    }
-    for(var assertion in allAssertions) {
-        var expectedValue = !!assertions[assertion]
-        if(functionNodeMethods[assertion].invoke(f) !== expectedValue) {
-            throw "Expected " + assertion + " === " + expectedValue + " for " + f;
-        }
-    }
-}
-
-// testFirstFn(script[, assertions...] tests whether all the specified
-// assertions are true in the first function in the given script; "script"
-// is a string with the source text of the script.
-function testFirstFn(script) {
-    arguments[0] = getFirstFunction(compile(script))
-    test.apply(null, arguments)
-}
-
-// ---------------------------------- ACTUAL TESTS START HERE --------------
-
-// The simplest possible functions have no attributes set
-testFirstFn("function f() { }")
-testFirstFn("function f(x) { x }")
-
-// A function referencing a global needs parent scope, and it needs callee
-// (because parent scope is passed through callee)
-testFirstFn("function f() { x }", 'needsCallee', 'needsParentScope')
-
-// A function referencing "arguments" will have to be vararg. It also needs
-// the callee, as it needs to fill out "arguments.callee".
-testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg')
-
-// A function referencing "arguments" will have to be vararg. If it is
-// strict, it will not have to have a callee, though.
-testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrictMode')
-
-// A function defining "arguments" as a parameter will not be vararg.
-testFirstFn("function f(arguments) { arguments }")
-
-// A function defining "arguments" as a nested function will not be vararg.
-testFirstFn("function f() { function arguments() {}; arguments; }")
-
-// A function defining "arguments" as a local variable will be vararg.
-testFirstFn("function f() { var arguments; arguments; }", 'isVarArg', 'needsCallee')
-
-// A self-referencing function defined as a statement doesn't need a self 
-// symbol, as it'll rather obtain itself from the parent scope.
-testFirstFn("function f() { f() }", 'needsCallee', 'needsParentScope')
-
-// A self-referencing function defined as an expression needs a self symbol,
-// as it can't obtain itself from the parent scope.
-testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol')
-
-// A child function accessing parent's variable triggers the need for scope
-// in parent
-testFirstFn("(function f() { var x; function g() { x } })", 'needsScope')
-
-// A child function accessing parent's parameter triggers the need for scope
-// in parent
-testFirstFn("(function f(x) { function g() { x } })", 'needsScope')
-
-// A child function accessing a global variable triggers the need for parent
-// scope in parent
-testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsCallee')
-
-// A child function redefining a local variable from its parent should not 
-// affect the parent function in any way
-testFirstFn("(function f() { var x; function g() { var x; x } })")
-
-// Using "with" unleashes a lot of needs: parent scope, callee, own scope, 
-// and all variables in scope. Actually, we could make "with" less wasteful,
-// and only put those variables in scope that it actually references, similar
-// to what nested functions do with variables in their parents.
-testFirstFn("(function f() { var o; with(o) {} })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope')
-
-// Using "eval" is as bad as using "with" with the added requirement of
-// being vararg, 'cause we don't know if eval will be using "arguments".
-testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasEval', 'isVarArg', 'hasDeepWithOrEval', 'allVarsInScope')
-
-// Nested function using "with" is pretty much the same as the parent
-// function needing with.
-testFirstFn("(function f() { function g() { var o; with(o) {} } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope')
-// Nested function using "eval" is almost the same as parent function using
-// eval, but at least the parent doesn't have to be vararg.
-testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope')
-
-// Function with 250 named parameters is ordinary
-testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }")
-
-// Function with 251 named parameters is variable arguments
-testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250, p251) { p250 = p251 }", 'isVarArg')